使用Knockoutjs ObservableArray确定添加或删除了哪个元素

时间:2012-08-28 20:23:02

标签: knockout.js datatables

我需要弄清楚从我的Knockout observableArray中删除了哪个元素。请参阅我的jsFiddle

我可以订阅更改,但它只返回value,即添加或删除后的当前数组。

self.selectedDataPointOptions.subscribe(function(value) {
  // how can I see which one was added or removed?
  alert(value);
});

3 个答案:

答案 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');
    }
);