Typescript 在可观察范围内观察所有属性变化

Typescript 在可观察范围内观察所有属性变化,typescript,knockout.js,knockout-3.0,Typescript,Knockout.js,Knockout 3.0,我正在使用KnockoutJS3.4 我的视图模型(TypeScript)如下所示: export class ItemsViewModel { public currentItem: KnockoutObservable<ItemViewModel>; public items: KnockoutObservableArray<KnockoutObservable<ItemViewModel>>; /* snip */ } 导出类I

我正在使用KnockoutJS3.4

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

export class ItemsViewModel {
    public currentItem: KnockoutObservable<ItemViewModel>;
    public items: KnockoutObservableArray<KnockoutObservable<ItemViewModel>>;
    /* snip */
}
导出类ItemsViewModel{
public currentItem:可观察的淘汰;
公共物品:击倒台;
/*剪断*/
}
ItemViewModel
包含一系列可观察的属性。其中包括
Id
Name
Description

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

我如何才能以最有效的方式做到这一点


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

为了确定修改了哪个属性,您需要一个不太通用的解决方案。您可以通过将扩展器附加到需要跟踪的每个属性来实现这一点。我会让扩展器接受一个视图模型级别的subscribable来通知,以及要扩展的属性的名称。(遗憾的是,JavaScript没有反射功能来使该部分代码成为可执行的)

然后在视图模型中添加subscribable和subscription

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 }})
    }
}

为了确定修改了哪个属性,您需要一个不太通用的解决方案。您可以通过将扩展器附加到需要跟踪的每个属性来实现这一点。我会让扩展器接受一个视图模型级别的subscribable来通知,以及要扩展的属性的名称。(遗憾的是,JavaScript没有反射功能来使该部分代码成为可执行的)

然后在视图模型中添加subscribable和subscription

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 }})
    }
}

如果您所说的高效是指开发人员的时间,那么您可以在视图模型上创建一个调用ko.toJS的计算属性。这将创建对视图模型中每个可观察对象的依赖关系,然后您可以订阅该属性。为了完整起见,使用
ko.toJS
您还可以只跟踪视图模型某些部分的更改。关于可能重复的问题,如果这个问题是关于效率/速度的,我会在这里注意到ko.toJS比ko.toJSON
knockoutobservearray
性能更好,为什么要将
可观察对象存储在
可观察阵列中?我建议你不要这么做。如果你说的高效是指开发人员的时间,那么你可以在你的视图模型上创建一个调用ko.toJS的计算属性。这将创建对视图模型中每个可观察对象的依赖关系,然后您可以订阅该属性。为了完整起见,使用
ko.toJS
您还可以只跟踪视图模型某些部分的更改。关于可能重复的问题,如果这个问题是关于效率/速度的,我会在这里注意到ko.toJS比ko.toJSON
knockoutobservearray
性能更好,为什么要将
可观察对象存储在
可观察阵列中?我建议反对。太好了,这完全是我想要的-非常感谢。太好了,这完全是我想要的-非常感谢。