我有一个带有observalbe项目数组的简单viewmodel,以及一个包含所选项目的observable。我订阅了所选项目的更改,我可以在我的测试中看到,即使我一次又一次地分配相同的值,处理程序也会被触发,所以不应该有任何改变。以下代码显示了3个相同的警报"更改为..."文本。
view.SelectedItem(view.Items()[0]);
view.SelectedItem.subscribe(function(newValue) {
alert("changed to " + ko.toJSON(newValue));
});
view.SelectedItem(view.Items()[0]);
view.SelectedItem(view.Items()[0]);
view.SelectedItem(view.Items()[0]);
这是demo fiddle。
答案 0 :(得分:1)
显然,选择一个项目,即使它与已经选择的项目相同,也会触发更改事件,调用订阅时指定的功能。
如果您希望在即将更改之前收到可观察值的通知,您可以订阅beforeChange事件。例如:
view.SelectedItem.subscribe(function(oldValue) {
alert("The previous value is " + oldValue);
}, null, "beforeChange");
<强> Source 强>
这可以帮助您确定值是否已更改。
答案 1 :(得分:1)
您可以创建函数来访问旧值和新值以进行比较:
ko.subscribable.fn.subscribeChanged = function(callback) {
var previousValue;
this.subscribe(function(oldValue) {
previousValue = oldValue;
}, undefined, 'beforeChange');
this.subscribe(function(latestValue) {
callback(latestValue, previousValue);
});
};
您可以使用ko扩展名将此功能添加到某个文件中。我曾经在stackoverflow上找到它,但现在无法记住链接。然后你可以像这样使用它:
view.SelectedItem.subscribeChanged(function(newValue, oldValue) {
if (newValue.Name != oldValue.Name || newValue.Quantity != oldValue.Quantity) {
alert("changed to " + ko.toJSON(newValue));
}
});
答案 2 :(得分:0)
我最终根据论坛上的帖子创建了自己的方法:
// Accepts a function(oldValue, newValue) callback, and triggers it only when a real change happend
ko.subscribable.fn.onChanged = function (callback) {
if (!this.previousValueSubscription) {
this.previousValueSubscription = this.subscribe(function (_previousValue) {
this.previousValue = _previousValue;
}, this, 'beforeChange');
}
return this.subscribe(function (latestValue) {
if (this.previousValue === latestValue) return;
callback(this.previousValue, latestValue);
}, this);
};