2012-08-28 13 views

risposta

24

Il knockout include ko.utils.compareArrays che è possibile utilizzare per confrontare un array con un altro. Ecco una funzione di supporto che notifica per ogni elemento aggiunto o rimosso nella matrice:

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

Eccolo in azione: http://jsfiddle.net/mbest/Jq3ru/

Cominciando con Knockout 3.0, è possibile utilizzare l'evento arrayChange per farlo più facilmente . Maggiori informazioni: http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/

+0

Grazie, ho inserito in e funziona benissimo! – Aligned

6

La soluzione proposta è interessante e funziona, ma comporta la clonazione dell'array ogni volta che si verifica un cambiamento, quindi esegue un confronto, che è probabilmente O (n^2).

Ecco un'altra soluzione: Significa tra cui un altro file js ... ma se volete un po 'di migliorare le prestazioni, questo fornirà esso:

https://github.com/bobwold/betterObservableArray

Questa sostituzione per observableArray (che è fondamentalmente solo una clone di array osservabile, con un po 'di codice in più) usa il framework di sottoscrizione ad eliminazione diretta e aggiunge "aggiungi" e "rimuovi" abbonamenti.

campione Uso:

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

...

function presidentAdded(president) { 
}; 

function presidentRemoved (president) { 
}; 

... La soluzione di

1

Michael migliori (subscribeArrayChanged) funziona molto bene anche per me. Ma ho bisogno di usarlo dal dattiloscritto e per questo motivo ho scritto una piccola fonte di definizione (d.ts), in una fonte diversa dall'originale 'knockout.d.ts' per usarlo in modo confortevole nel codice sorgente dattiloscritto. il file

knockoutext.d.ts personalizzati:

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

piccolo frammento di codice di esempio:

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