2012-08-28 37 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'); 
    } 
); 
相关问题