Determine which element was added or removed with

2020-02-26 06:24发布

I need to figure out which element was removed from my Knockout observableArray. Please see my jsFiddle.

I can subscribe to the change, but it only returns value, which is the current array after the add or remove.

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

3条回答
我欲成王,谁敢阻挡
2楼-- · 2020-02-26 07:01

Michael Best's solution (subscribeArrayChanged) works very well for me too. But I need to use it from typescript and for this reason I wrote a little define source (d.ts), in a different source from original 'knockout.d.ts' for using it in a comfortable way in typescript source code.

custom knockoutext.d.ts file:

/// <reference path="knockout.d.ts" />
interface KnockoutObservableArray<T> extends KnockoutObservableArrayFunctions<T> {
    subscribeArrayChanged(addCallback: (T) => void , deleteCallback: (T) => void );
}

Little sample code snippet:

data[0].Properties.subscribeArrayChanged(
    (value: Meta.Data.Property) => {
        console.log('add callback called');
    },
    (value: Meta.Data.Property) => {
        console.log('delete callback called');
    }
); 
查看更多
小情绪 Triste *
3楼-- · 2020-02-26 07:05

The proposed solution is cool, and works, but it involves cloning the array every time there is a change, then doing a compare, which is probably O(n^2).

Here is another solution: It means including another js file... but if you want some better performance, this will provide it:

https://github.com/bobwold/betterObservableArray

This replacement for observableArray (which is basically just a clone of observable array, with some extra code) uses the knockout subscription framework, and adds "add" and "remove" subscriptions.

Sample Usage:

var presidents = ko.betterObservableArray();
presidents.subscribe(presidentAdded, this, "add");
presidents.subscribe(this.presidentRemoved, this, "remove");

...

function presidentAdded(president) {
};

function presidentRemoved (president) {
};

...

查看更多
甜甜的少女心
4楼-- · 2020-02-26 07:20

Knockout includes ko.utils.compareArrays which you can use to compare one array to another. Here's a helper function that notifies for each added or removed item in the array:

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

Here it is in action: http://jsfiddle.net/mbest/Jq3ru/

Beginning with Knockout 3.0, you can use the arrayChange event to do this more easily. More info is here: http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/

查看更多
登录 后发表回答