订阅observable数组只有新的或删除的条目

所以是的,我可以订阅一个可观察数组:

vm.myArray = ko.observableArray(); vm.myArray.subscribe(function(newVal){...}); 

问题是传递给函数的newVal是整个数组。 无论如何,我只能得到三angular洲的一部分? 说添加删除的元素?

从KnockoutJS 3.0起, ko.observableArray上有一个arrayChange订阅选项 。

 var myArray = ko.observableArray(["Alpha", "Beta", "Gamma"]); myArray.subscribe(function(changes) { // For this example, we'll just print out the change info console.log(changes); }, null, "arrayChange"); myArray.push("newitem!"); 

在上面的callback中,更改参数将是这样一个变化对象的数组:

 [ { index: 3, status: 'added', value: 'newitem!' } ] 

针对您的特定问题, 您希望收到新的或删除的项目的通知 。 为了实现使用Knockout 3,它看起来像这样:

 myArray.subscribe(function(changes) { changes.forEach(function(change) { if (change.status === 'added' || change.status === 'deleted') { console.log("Added or removed! The added/removed element is:", change.value); } }); }, null, "arrayChange"); 

由于我在其他地方找不到任何信息,所以我会添加一个关于如何在TypeScript中使用的回复。

这里的关键是使用KnockoutArrayChange接口作为TEvent进行订阅。 如果你不这样做,它会尝试使用其他(非通用)订阅,并会抱怨状态,索引和值不存在。

 class ZoneDefinition { Name: KnockoutObservable<String>; } class DefinitionContainer { ZoneDefinitions: KnockoutObservableArray<ZoneDefinition>; constructor(zoneDefinitions?: ZoneDefinition[]){ this.ZoneDefinitions = ko.observableArray(zoneDefinitions); // you'll get an error if you don't use the generic version of subscribe // and you need to use the KnockoutArrayChange<T> interface as T this.ZoneDefinitions.subscribe<KnockoutArrayChange<ZoneDefinition>[]>(function (changes) { changes.forEach(function (change) { if (change.status === 'added') { // do something with the added value // can use change.value to get the added item // or change.index to get the index of where it was added } else if (change.status === 'deleted') { // do something with the deleted value // can use change.value to get the deleted item // or change.index to get the index of where it was before deletion } }); }, null, "arrayChange"); } 

为了只检测push()remove()事件,而不移动项目,我把这些可观察的数组函数包装。

 var trackPush = function(array) { var push = array.push; return function() { console.log(arguments[0]); push.apply(this,arguments); } } var list = ko.observableArray(); list.push = trackPush(list); 

最初的推送函数存储在一个闭包中,然后覆盖一个包装,使我可以做任何我想要的东西与被推入的项目之前或之后,它被推入arrays。

类似于remove()模式。

我正在使用一个类似但不同的方法,跟踪一个元素是否已经插入元素本身:

 myArray.subscribe(function(array){ $.each(array, function(id, el) { if (!el.instrumented) { el.instrumented = true; el.displayName = ko.computed(function(){ var fn = $.trim(el.firstName()), ln = $.trim(el.lastName()); if (fn || ln) { return fn ? (fn + (ln ? " " + ln : "")) : ln; } else { return el.email(); } }) } }); }) 

但是,这是非常乏味的,模式在我的代码中重复出现

没有我知道的。 想知道我在做什么? 我使用一个以前的variables来保存这个值,这个东西叫selectedItem

 vm.selectedItem = ko.observable({}); function addToArray(item) { vm.selectedItem(item); vm.myArray.push(item); } 

那么,当我的可观察数组发生什么事情时,我知道哪个项目被添加了。

 vm.myArray.subscribe(function(newArray) { var addedItem = vm.selectedItem(item); ... } 

这真的很冗长,假设你的数组拥有多种数据,你需要有一些帮助你知道如何处理你保存的variables的标志。

 vm.myArray.subscribe(function(newArray) { if ( wasUpdated ) // do something with selectedItem else // do whatever you whenever your array is updated } 

需要注意的一个重要的事情是,如果知道是否使用pushunshift则可能知道添加了哪个项目。 只要浏览数组的最后一项或第一个,瞧。

尝试vm.myArray().arrayChanged.subscribe(function(eventArgs))

添加项目时具有附加值,删除项目时删除值。