我正在使用KnockoutJS 3.4。
我的视图模型(TypeScript)如下所示:
export class ItemsViewModel {
public currentItem: KnockoutObservable<ItemViewModel>;
public items: KnockoutObservableArray<KnockoutObservable<ItemViewModel>>;
/* snip */
}
ItemViewModel
包含一堆可观察的属性。其中包括Id
,Name
和Description
。
我希望能够订阅currentItem
内发生的更改。使用currentItem.subscribe
监视来更改currentItem
可观察值,而不是当前项目中的属性。我已经看到另一个被建议为重复的问题,但它只是跟踪整个对象的更改 - 我想知道特定属性何时在该对象上发生更改。
我怎样才能以最有效的方式做到这一点?
编辑我已阅读评论及相关问题。它不识别已更改的属性。我已经更新了这个问题以反映这一点。
答案 0 :(得分:2)
为了确定修改了哪个属性,您需要一个不太通用的解决方案。您可以通过将扩展程序附加到需要跟踪的每个属性来执行此操作。我希望扩展程序接受可订阅的视图模型级别,以及要扩展的属性的名称。 (遗憾的是,JavaScript没有反映使该部分能够编码)
ko.extenders.trackChange = function (target, options) {
target.subscribe(function (newValue) {
if (ko.isSubscribable(options.notifier)) options.notifier.notifySubscribers(options.propertyName);
});
return target;
};
然后在您的视图模型中添加可订阅和订阅。
self.propertyChanged = new ko.subscribable();
self.propertyChanged.subscribe(function(propertyName){
console.log(propertyName + " was updated");
});
最后将扩展程序添加到您的属性中。
self.property1 = ko.observable(0).extend({trackChange: { propertyName: 'property1', notifier: self.propertyChanged }});
self.property2 = ko.observable(0).extend({trackChange: { propertyName: 'property2', notifier: self.propertyChanged }});
self.property3 = ko.observable(0).extend({trackChange: { propertyName: 'property3', notifier: self.propertyChanged }});
如果你想在每一个属性上使用它,你可以自动地在视图模型上使用循环附加扩展器:
self.property1 = ko.observable();
self.property2 = ko.observable();
self.property3 = ko.observable();
for (key in self) {
if (self.hasOwnProperty(key) && ko.isObservable(self[key])) {
self[key].extend({trackChange: { propertyName: key, notifier: self.propertyChanged }})
}
}