【ASP.NET MVC】【VB】ASP.NET MVC で変更検知を考える ~knockout.js利用版~

はじめに

http://blogs.yahoo.co.jp/dk521123/35963034.html
のつづき。
今回は、変更した後に変更部分を元に戻した場合、変更していないと判断してくれるように作る

サンプル

 * 以下の関連記事を元にしている。ビュー以外のモデル、コントローラについては以下を参照。
http://blogs.yahoo.co.jp/dk521123/35956746.html
 * ASP.NET MVC + knockout.jsだと大抵ではajaxを使ったサンプルが多いが、
   今回のサンプルでは、(実験的な意味で)ajaxを使わずに、
   サーバとのやり取りを一回だけにしたサンプルにしてみた
 # ソースの作り的にはajaxを使った方が綺麗にコーディングできる

■knockout.js利用版

 * 以下の関連記事で取り扱った knockout.js を利用する。
http://blogs.yahoo.co.jp/dk521123/35949660.html
外部JabaScript:/Scripts/ChangeValuesTracker.js
function ChangeTracker(root, isInitiallyDirty) {
    var result = function() {}
    var initialState = ko.observable(ko.toJSON(root));
    var isInitiallyDirty = ko.observable(isInitiallyDirty);
 
    result.isDirty = ko.dependentObservable(function() {
        return isInitiallyDirty() || initialState() !== ko.toJSON(root);
    });
 
    result.reset = function() {
        initialState(ko.toJSON(root));
        isInitiallyDirty(false);
    };
 
    return result;
};

function setViewModelToCheckChagingValues(viewModel) {
    viewModel.tracker = new ChangeTracker(viewModel, false);
    viewModel.move = function() {
        if (viewModel.tracker.isDirty()) {
            return window.confirm('You have some changes.\nAre you sure you want to go to the other pages?');
        }
        return true;
    }
    ko.applyBindings(viewModel);
}

function parseBoolean(targetValue) {
    if (!targetValue) {
        return false;
    }
   
    return (targetValue.toLowerCase()) == "true";
}
ビュー:Index.vbhtml
@ModelType WebAppli.Models.EmployeeListModel

@Code
    ViewData("Title") = "Index"
    Dim index As Integer = 0
End Code

@Using (Html.BeginForm("SendResult", "SampleMvc", FormMethod.Post, New With {.Id = "formID"}))
    @<table>
        <thead>
            <tr>
                <th>Delete?</th>
                <th>ID</th>
                <th>Name</th>
            </tr>
        </thead>
         <tbody data-bind="foreach: employees">
             <tr>
                 <td><input type="checkbox"
                            data-bind="checked: isChecked, attr: { value: isChecked, name: 'Employees[' + $index() + '].IsChecked' }" /></td>
                 <td><input type="text"
                            data-bind="value: employeeId, attr: { name: 'Employees[' + $index() + '].EmployeeId' }" /></td>
                 <td><input type="text"
                            data-bind="value: employeeName, attr: { name: 'Employees[' + $index() + '].EmployeeName' }" /></td>
             </tr>
         </tbody>
    </table>
    @<input type="submit" value="Send" />
    @<a href="http://www.yahoo.co.jp/" data-bind="click: move">Go yahoo!</a>
End Using

<script src="@Url.Content("~/Scripts/knockout-3.4.0.debug.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ChangeValuesTracker.js")" type="text/javascript"></script>
<script type="text/javascript">
    function Employee(isChecked, id, name) {
        this.isChecked = ko.observable(parseBoolean(isChecked));
        this.employeeId = ko.observable(id);
        this.employeeName = ko.observable(name);
    }

    function ViewModel(models) {
        this.employees = ko.observableArray(models);
    }

    var models = [];
        @Code
            For Each employee In Model.Employees
        @<text>
    var model = new Employee('@employee.IsChecked', '@employee.EmployeeId', '@employee.EmployeeName');
    models.push(model);
        </text>
            Next
    End Code

    setViewModelToCheckChagingValues(new ViewModel(models));
</script>

knockout.jsを使用すると、HTMLヘルパーって使わないなーってことで、以下の関連記事で、HTMLヘルパーを使ったパターンを考える
http://blogs.yahoo.co.jp/dk521123/35967929.html

関連記事

ASP.NET MVC でリストのモデルを表示する

http://blogs.yahoo.co.jp/dk521123/35956746.html

knockout.js を使った変更検知(ダーティ・チェック)を考える [2]

http://blogs.yahoo.co.jp/dk521123/35949660.html

JavaScript で、Booleanに変換した際の注意事項

http://blogs.yahoo.co.jp/dk521123/35620716.html

ASP.NET MVC で変更検知を考える ~簡易版~

http://blogs.yahoo.co.jp/dk521123/35963034.html

ASP.NET MVC で変更検知を考える ~hiddenを使った版~

http://blogs.yahoo.co.jp/dk521123/35967929.html