2013-01-04 6 views

risposta

108

A partire da KnockoutJS 3.0, c'è un arrayChange subscription option su ko.observableArray.

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!"); 

Nella richiamata sopra, l'argomento cambia sarà un array di oggetti cambiamento come questo:

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

Per il vostro problema specifico, si desidera ricevere la notifica di nuovi o rimossi elementi. Per implementare che l'utilizzo di Knockout 3, che sarebbe simile a questa:

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"); 
+0

qual è lo stato di un individuo 'modificato'? – beauXjames

+0

Non capisco cosa stai chiedendo quando dici "individuo modificato". –

+0

individuale == istanza di modifiche == modifica ['added', 'deleted', '???', '???', ... ???] – beauXjames

-1

Nessuno che io conosca. Vuoi sapere cosa faccio? Io uso una variabile precedente per contenere il valore, qualcosa chiamato selectedItem

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

in modo che modo, quando succede qualcosa a mio allineamento osservabile, lo so che voce è stata aggiunta.

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

Questo è veramente verboso, e assumendo l'array contiene molti tipi di dati, si avrebbe bisogno di avere una sorta di bandiere che ti aiuta a sapere che cosa fare con le variabili salvate ...

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

Una cosa importante da notare è che potresti sapere quale articolo è stato aggiunto se sai se è stato utilizzato push o unshift. Basta sfogliare l'ultimo elemento dell'array o il primo e voilà.

+0

Sto usando un approccio diverso: tieni traccia se un elemento è stato strumentato nell'elemento stesso. Vedere la mia risposta sopra –

0

Sto usando un approccio simile, ma diverso, tenere traccia se un elemento è stato strumentato nell'elemento stesso:

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

Ma è davvero noioso e il modello ripetuto in tutto il mio codice

+0

Per salvare te stesso una proprietà, è possibile utilizzare: if (! ('DisplayName' in el)) {} – GrantDG

-1

Try vm.myArray().arrayChanged.subscribe(function(eventArgs))

Questo ha il valore aggiunto quando viene aggiunto un elemento e il valore rimosso quando viene rimosso un elemento.

7

Dal momento che non ho trovato alcuna informazione su questo altrove, aggiungerò una risposta su come usare questo con dattiloscritto.

La chiave qui era usare l'interfaccia KnockoutArrayChange come TEvent per iscriversi. Se non lo fai, cercherà di utilizzare l'altro (non generico) subscribe e si lamenterà di status, indice e valore non esistenti.

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

Per rilevare solo push() e remove() eventi e non oggetti in movimento, ho messo un involucro intorno a queste funzioni di matrice osservabili.

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

La funzione push originale viene memorizzato in una chiusura, poi viene sovrapposto con un wrapper che mi permette faccio tutto quello che voglio con la voce spinto prima, o dopo, si è spinto sulla matrice.

Modello simile per remove().