KO範例5 - 即時反應物件屬性變化
0 |
在範例4使用了totalScore ko.computed函數即時加總全部使用者的積分,經實實測,新增或移除資料時積分總和會立即改變。如果是修改某一筆使用者績分呢?
$("#btnChgScore").click(function () {
vm.users()[0].score = 9999;
});
我們加入一個按鈕模擬修改積分的情境,程式先用vm.users()傳回UserViewModel物件陣列(因為users是ko.observableArray,當成函數呼叫才會傳回JavaScript Array形式的資料),取出第0筆,將其score改為9999。
來看線上展示:
咦? 按了沒反應? 是的,前述做法有個問題,如果期望KO能即時感應屬性變化,UserViewModel的score就必須用ko.observable()而非單純JavaScript物件屬性,所以程式需稍作修改:
function UserViewModel(id, name, score) {
var self = this;
self.id = id;
self.name = name;
//改為observalbe
self.score = ko.observable(score);
}$("#btnChgScore").click(function () {
//改用score()設定內容
vm.users()[0].score(9999);
});
提醒: ko.observable型屬性要設定新值時,要透過函數方式呼叫,不要呆呆地直接指定。(剛開始用KO時,我就常幹這種傻事)
修正過的版本,就可以正常運作囉~~
完整程式碼如下:
<!DOCTYPE html>
<html>
<head>
<title>Lab 5 - 即時反應陣列物件的屬性變化</title>
<script src="../Scripts/jquery-1.7.2.js"></script>
<script src="../Scripts/knockout-2.1.0.debug.js"></script>
<script>
//很簡單的User資料物件
function UserViewModel(id, name, score) {
var self = this;
self.id = id;
self.name = name;
//改為observalbe
self.score = ko.observable(score);
}
function MyViewModel() {
var self = this;
self.users = ko.observableArray();
//移除User,輸入參數為user物件
//foreach產生的元素,click事件時會帶入該元素所繫結的資料物件
self.removeUser = function(user) {
self.users.remove(user);
}
//分數加總,透過神奇的Dendency Tracking功能
//一旦有任何User分數更動,它就會自動更新
self.totalScore = ko.computed(function () {
var total = 0;
$.each(self.users(), function (i, u) {
//改用.score()
total += u.score();
});
return total;
});
}
$(function () {
var vm = new MyViewModel();
//預先增加一些User
vm.users.push(
new UserViewModel("M1", "Jeffrey", 32767));
vm.users.push(
new UserViewModel("M2", "Darkthread", 65535));
//按鈕時動態增加User
var c = 2;
$("#btnAddUser").click(function () {
var now = new Date(); //用時間產生隨機屬性值
vm.users.push(new UserViewModel(
"M" + c++,
"P" + "-" + now.getSeconds() * now.getMilliseconds(),
now.getMilliseconds()));
});
$("#btnChgScore").click(function () {
//改用score()設定內容
vm.users()[0].score(9999);
});
ko.applyBindings(vm);
});
</script>
<style>
table { width: 400px }
td,th { border: 1px solid gray; text-align: center }
</style>
</head>
<body>
<input type="button" value="新增User" id="btnAddUser" />
共 <span data-bind="text: users().length"></span> 筆,
合計 <span data-bind="text: totalScore"></span> 分
<table>
<thead>
<tr><th>Id</th><th>姓名</th><th>積分</th><th></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" style='text-align: right'></span></td>
<td><a href='#' data-bind="click: $root.removeUser">移除</a></td>
</tr>
</tbody>
</table>
<input type="button" value="測試Score變更" id="btnChgScore" />
</body>
</html>
[KO系列]
http://www.darkthread.net/kolab/labs/default.aspx?m=post
Comments
Be the first to post a comment