我需要弄清楚从我的Knockout observableArray中删除了哪个元素。请参阅我的jsFiddle。
我可以订阅更改,但它只返回value,即添加或删除后的当前数组。
self.selectedDataPointOptions.subscribe(function(value) {
// how can I see which one was added or removed?
alert(value);
});
答案 0 :(得分:24)
Knockout包含ko.utils.compareArrays
,可用于将一个数组与另一个数组进行比较。这是一个帮助函数,它通知数组中每个添加或删除的项目:
ko.observableArray.fn.subscribeArrayChanged = function(addCallback, deleteCallback) {
var previousValue = undefined;
this.subscribe(function(_previousValue) {
previousValue = _previousValue.slice(0);
}, undefined, 'beforeChange');
this.subscribe(function(latestValue) {
var editScript = ko.utils.compareArrays(previousValue, latestValue);
for (var i = 0, j = editScript.length; i < j; i++) {
switch (editScript[i].status) {
case "retained":
break;
case "deleted":
if (deleteCallback)
deleteCallback(editScript[i].value);
break;
case "added":
if (addCallback)
addCallback(editScript[i].value);
break;
}
}
previousValue = undefined;
});
};
这里有效:http://jsfiddle.net/mbest/Jq3ru/
从Knockout 3.0开始,您可以使用arrayChange
事件更轻松地执行此操作。更多信息请访问:http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/
答案 1 :(得分:6)
建议的解决方案很酷,并且有效,但它涉及每次发生更改时克隆数组,然后进行比较,这可能是O(n ^ 2)。
这是另一种解决方案:它意味着包含另一个js文件......但如果你想要一些更好的性能,这将提供它:
https://github.com/bobwold/betterObservableArray
observableArray的替代品(基本上只是可观察数组的一个克隆,带有一些额外的代码)使用了淘汰订阅框架,并添加了“添加”和“删除”订阅。
样本用法:
var presidents = ko.betterObservableArray();
presidents.subscribe(presidentAdded, this, "add");
presidents.subscribe(this.presidentRemoved, this, "remove");
...
function presidentAdded(president) {
};
function presidentRemoved (president) {
};
...
答案 2 :(得分:1)
Michael Best的解决方案(subscribeArrayChanged)也适用于我。但是我需要从typescript中使用它,因此我在一个与原始'knockout.d.ts'不同的来源中编写了一个小的定义源(d.ts),以便在打字稿源代码中以一种舒适的方式使用它。 / p>
自定义knockoutext.d.ts文件:
/// <reference path="knockout.d.ts" />
interface KnockoutObservableArray<T> extends KnockoutObservableArrayFunctions<T> {
subscribeArrayChanged(addCallback: (T) => void , deleteCallback: (T) => void );
}
小示例代码段:
data[0].Properties.subscribeArrayChanged(
(value: Meta.Data.Property) => {
console.log('add callback called');
},
(value: Meta.Data.Property) => {
console.log('delete callback called');
}
);