2012-08-28 8 views
15

Potrzebuję dowiedzieć się, który element został usunięty z obserwowalnego obiektu Knockout observableArray. Proszę zobaczyć mój jsFiddle.Określić, który element został dodany lub usunięty za pomocą obiektu Knockoutjs ObservableArray

Mogę zasubskrybować zmianę, ale zwraca ona tylko wartość, która jest bieżącą tablicą po dodaniu lub usunięciu.

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

Odpowiedz

24

Knockout obejmuje ko.utils.compareArrays których można użyć, aby porównać jednej tablicy do drugiej. Oto funkcja pomocnika, który powiadamia dla każdego dodanego lub usuniętego elementu w tablicy:

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

Oto ona w akcji: http://jsfiddle.net/mbest/Jq3ru/

Poczynając Knockout 3.0, można użyć zdarzenia arrayChange to zrobić łatwiej . Więcej informacji znajduje się tutaj: http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/

+0

dziękuję, podłączyłem go i działa świetnie! – Aligned

6

Proponowane rozwiązanie jest fajne i działa, ale wiąże się z klonowaniem tablicy za każdym razem, gdy następuje zmiana, a następnie porównaniem, które prawdopodobnie ma postać O (n^2).

Oto inne rozwiązanie: To znaczy w tym innym pliku js ... ale jeśli chcesz trochę lepszą wydajność, to będzie ją przedstawić:

https://github.com/bobwold/betterObservableArray

Ten zastępczy dla observableArray (co jest w zasadzie tylko klon tablicy obserwowalnej, z dodatkowym kodem) używa frameworka subskrypcji typu "knockout" i dodaje subskrypcje "dodaj" i "usuń".

Próbka Zastosowanie:

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

...

function presidentAdded(president) { 
}; 

function presidentRemoved (president) { 
}; 

... rozwiązanie

1

Michaela Besta (subscribeArrayChanged) działa bardzo dobrze dla mnie. Ale muszę użyć go z maszynopisu iz tego powodu napisałem małe źródło definicji (d.ts), w innym źródle niż oryginalny "knockout.d.ts", aby używać go wygodnie w kodzie źródłowym maszynopisu. złożyć

niestandardowe knockoutext.d.ts:

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

Mała przykładowy fragment kodu:

data[0].Properties.subscribeArrayChanged(
    (value: Meta.Data.Property) => { 
     console.log('add callback called'); 
    }, 
    (value: Meta.Data.Property) => { 
     console.log('delete callback called'); 
    } 
);