观察 observable 中的所有 属性 变化

Observing all property changes within an observable

我正在使用 KnockoutJS 3.4。

我的视图模型 (TypeScript) 如下所示:

export class ItemsViewModel {
    public currentItem: KnockoutObservable<ItemViewModel>;
    public items: KnockoutObservableArray<KnockoutObservable<ItemViewModel>>;
    /* snip */
}

ItemViewModel 包含一堆可观察的属性。其中包括 IdNameDescription

我希望能够订阅 currentItem 内发生的更改。使用 currentItem.subscribe 监视 currentItem 可观察值的变化,而不是当前项目中的属性。我已经看到另一个被建议为重复的问题,但它只是跟踪整个对象的变化 - 我想知道该对象的特定 属性 何时发生变化。

我怎样才能以最有效的方式做到这一点?

编辑 我已阅读评论和相关问题。它不识别更改的 属性。我已经更新了这个问题以反映这一点。

为了确定哪个 属性 被修改,您需要一个不太通用的解决方案。您可以通过将扩展器附加到每个需要跟踪的 属性 来实现。我会让扩展器接受可订阅的视图模型级别通知,以及扩展的 属性 的名称。 (遗憾的是 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 }})
    }
}