2012-08-28 19 views

Respuesta

24

Knockout incluye ko.utils.compareArrays que se puede utilizar para comparar una matriz a otra. He aquí una función auxiliar que se notifica para cada elemento añadido o eliminado de la matriz:

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

Aquí está en acción: http://jsfiddle.net/mbest/Jq3ru/

Comenzando con Knockout 3.0, se puede utilizar el evento arrayChange hacer esto con mayor facilidad . Más información está aquí: http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/

+0

Gracias, enchufé y funciona muy bien! – Aligned

6

La solución propuesta es genial, y funciona, pero implica clonar la matriz cada vez que hay un cambio, luego hacer una comparación, que es probablemente O (n^2).

Aquí hay otra solución: Significa que incluye otro archivo js ... pero si quieres algo mejor rendimiento, esto proporcionará que:

https://github.com/bobwold/betterObservableArray

Este reemplazo para observableArray (que es básicamente una clon de la matriz observable, con algún código adicional) utiliza el marco de suscripción knockout y agrega suscripciones "agregar" y "eliminar".

Ejemplo de uso:

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

...

function presidentAdded(president) { 
}; 

function presidentRemoved (president) { 
}; 

... La solución de

1

Michael Mejor (subscribeArrayChanged) funciona muy bien para mí también. Pero necesito usarlo desde un texto mecanografiado y por esta razón escribí una fuente de definición pequeña (d.ts), en una fuente diferente de la original 'knockout.d.ts' para usarla de una manera cómoda en el código fuente de mecanografía. presentar

knockoutext.d.ts personalizados:

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

pequeño fragmento de código de ejemplo:

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