实时反映对象属性的变化

在前一篇博客中我们使用了如下代码去新增user对象,即push方法:

$("#btnAddUser").click(function () { 
                vm.users.push(new UserViewModel(
                    $("#u_id").val(),
                    $("#u_name").val(),
                    parseInt($("#u_score").val())));
            });

使用 ko.computed去动态的计算user对象的socre属性的总和,前面有朋友问到修改之类的问题,我们尝试着添加一个按钮利用下面的代码试试:

$("#btnUpdateScore").click(function () { 
     vm.users()[0].score = 125; 
}); 

我们发现丝毫没有反应,其实就是我们想当然的认为使用了 ko.observableArray()就可以自动检测属性,其实他只是监控对象,而不是对象中的属性,因此,要让对象的属性也成为监控属性的话,我们就要回过头来使用ko.observable(),只要稍微已修改里面就OK了:

function UserViewModel(id, name, score) { 
var self = this; 
self.id = id; 
self.name = ko.observable(name); 
//改为observalbe 
self.score = ko.observable(score); 
} 

$("#btnUpdateScore").click(function () { //设定内容 vm.users()[0].score(125).name("HelloWorld!"); });

我们来修改新增对象的score和name来看看效果如何:

完整代码如下:

<!DOCTYPE html>
<html>
    
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>
            Index2
        </title>
        <script src="~/Scripts/jquery-2.0.3.js">
        </script>
        <script src="~/Scripts/knockout-2.3.0.js">
        </script>
        <script type="text/javascript">
            //定义user数据对象
            function UserViewModel(id, name, score) {
                var self = this;
                self.id = id;
                self.name = ko.observable(name);
                self.score = ko.observable(score);
            }
            //定义ViewModel
            function ViewModel() {
                var self = this;
                self.users = ko.observableArray(); //添加动态监视数组对象
                self.removeUser = function(user) {
                    self.users.remove(user);
                }
                self.totalscore = ko.computed(function() {
                    var total = 0;
                    $.each(self.users(),
                    function(i, u) {
                        total += u.score();
                    })
                    return total;
                });
            };
            $(function() {
                var vm = new ViewModel();
                //预先添加一些数据
                vm.users.push(new UserViewModel("d1", "rohelm", 121));
                vm.users.push(new UserViewModel("d2", "halower", 125));
                $("#btnAddUser").click(function() {
                    vm.users.push(new UserViewModel(
                    $("#u_id").val(), $("#u_name").val(), parseInt($("#u_score").val())));
                });
                $("#btnUpdateScore").click(function() {
                    vm.users()[vm.users().length - 1].score(125).name("HelloWorld!");
                });
                ko.applyBindings(vm);
            });
        </script>
    </head>
    
    <body>
        <section style="margin:250px">
            <section>
                ID
                <input type="text" id="u_id" style="width:30px">
                Name
                <input type="text" id="u_name" style="width:30px">
                Score
                <input type="text" id="u_score" style="width:30px">
                <br/>
                <input value="Add" id="btnAddUser" type="button" style="width:200px; background-color:#ff6a00;"
                />
                <br/>
                共
                <span data-bind="text: users().length">
                </span>
                条--------------合计
                <span data-bind="text: totalscore">
                </span>
                分
            </section>
            <section>
                <table>
                    <thead>
                        <tr>
                            <th>
                                ID
                            </th>
                            <th>
                                Name
                            </th>
                            <th>
                                Score
                            </th>
                            <th>
                                Option
                            </th>
                        </tr>
                    </thead>
                    <tbody data-bind="foreach: users">
                        <tr>
                            <td>
                                <span data-bind="text: id">
                                </span>
                            </td>
                            <td>
                                <span data-bind="text: name">
                                </span>
                            </td>
                            <td>
                                <span data-bind="text: score">
                                </span>
                            </td>
                            <td>
                                <a href='#' data-bind="click: $root.removeUser">
                                    Remove
                                </a>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <input value="Update测试" id="btnUpdateScore" type="button" style="width:200px; background-color:#ff6a00;"
                />
                <br/>
            </section>
        </section>
    </body>

</html>

运行效果: