给定以下HTML/JS(http://jsfiddle.net/mgs_jsfiddle/gUhm2/)
<div data-bind="foreach: users">
<p data-bind="click: $root.onClick">
<span data-bind="text: id"></span>
<span data-bind="text: firstName"></span>
<span data-bind="text: $root.isSelected($data)"></span>
</p>
</div>
$(function() {
function ViewModel() {
var self = this;
self.users = [
{ id: 1, firstName: "Bob" },
{ id: 2, firstName: "David" },
{ id: 3, firstName: "Walter" }
];
self.selectedId = ko.observable(1);
self.isSelected = function(user) {
return user.id === self.selectedId() ? "YES" : "NO";
};
self.onClick = function(user) {
self.selectedId(user.id);
}
};
ko.applyBindings(new ViewModel());
});
显示一个列表。通过单击一行,该行的ID将存储在
selectedId
中。我不明白,当更改
isSelected
时,为什么要重新评估函数selectedId
。毕竟,这是无法计算的。为什么仍然要重新评估? 最佳答案
发生这种情况是因为isSelected()
方法访问selectedId
属性(即observable
)。考虑一下:
HTML
<!-- adding into the foreach: block -->
<span data-bind="text: $root.someFunc()"></span>
<span data-bind="text: $root.someOtherFunc()"></span>
JS
// adding to a model definition
self.someFunc = function() {
self.selectedId();
console.log('I AM AN OBSERVER');
return 'oi: ' + Math.random();
};
self.someOtherFunc = function() {
// self.selectedId();
console.log('AND I AM NOT');
return 'no: ' + Math.random();
}
Fiddle。
如您所见,这两个函数之间的唯一区别是,第一个函数确实检查了定义为
ko.observable
的模型属性的值。因此,每次更改self.selectedId
时,都会向此功能通知此功能(这实际上意味着它会重新运行)。请注意,如果删除相应的
data-bind
部分,则该方法将不会在 View 初始化阶段运行,因此无法注册为适当的观察者。第二种方法虽然也在初始化阶段调用,但它不会尝试检查
selectedId
值-因此它没有注册为该值的观察者,也没有随后被调用。