2012-08-28 68 views

回答

24

基因敲除包括ko.utils.compareArrays,您可以使用它來比較一個數組與另一個數組。以下是通知的陣列中的每個添加或刪除項目的輔助功能:

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

這是在行動:http://jsfiddle.net/mbest/Jq3ru/

與淘汰賽3.0開始,您可以使用arrayChange事件更容易做到這一點。更多的信息在這裏:http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/

+0

謝謝你,我插上它和它的偉大工程! – Aligned

6

建議的解決方案很酷,並且可以工作,但它涉及每次發生更改時克隆數組,然後進行比較,可能是O(n^2)。

這裏是另一種解決方案:它意味着包括另一個js文件...但是,如果你想一些更好的性能,這將提供它:

https://github.com/bobwold/betterObservableArray

這種替代observableArray(這基本上是一個可觀察數組的克隆,以及一些額外的代碼)使用敲除訂閱框架,並添加「添加」和「刪除」訂閱。

用法示例:

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

...

function presidentAdded(president) { 
}; 

function presidentRemoved (president) { 
}; 

...

1

麥可思的解決方案(subscribeArrayChanged)都非常好,我也一樣。但我需要從打字稿中使用它,因此我在原始「knockout.d.ts」的不同來源中編寫了一個定義源文件(d.ts),以便在打字稿源代碼中以舒適的方式使用它。

定製knockoutext.d.ts文件:

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

小示例代碼段:

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