使用 Knockoutjs ObservableArray 确定添加或删除了哪个元素

Posted

技术标签:

【中文标题】使用 Knockoutjs ObservableArray 确定添加或删除了哪个元素【英文标题】:Determine which element was added or removed with a Knockoutjs ObservableArray 【发布时间】:2012-08-23 10:00:16 【问题描述】:

我需要弄清楚从我的 Knockout observableArray 中删除了哪个元素。请看我的jsFiddle。

我可以订阅更改,但它只返回值,即添加或删除后的当前数组。

self.selectedDataPointOptions.subscribe(function(value) 
  // how can I see which one was added or removed?
  alert(value);
);

【问题讨论】:

【参考方案1】:

Knockout 包括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/

从 Knockout 3.0 开始,您可以使用 arrayChange 事件更轻松地执行此操作。更多信息在这里:http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/

【讨论】:

【参考方案2】:

建议的解决方案很酷,并且有效,但它涉及每次发生变化时克隆数组,然后进行比较,这可能是 O(n^2)。

这是另一个解决方案:这意味着包含另一个 js 文件...但是如果您想要更好的性能,这将提供它:

https://github.com/bobwold/betterObservableArray

这个 observableArray 的替代品(它基本上只是 observable 数组的一个克隆,带有一些额外的代码)使用了淘汰订阅框架,并添加了“添加”和“删除”订阅。

示例用法:

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

...

function presidentAdded(president) 
;

function presidentRemoved (president) 
;

...

【讨论】:

【参考方案3】:

Michael Best 的解决方案 (subscribeArrayChanged) 对我也很有效。但是我需要从 typescript 中使用它,因此我在与原始 'knockout.d.ts' 不同的源中编写了一个小定义源 (d.ts),以便在 typescript 源代码中以舒适的方式使用它。

自定义 knockouttext.d.ts 文件:

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

小示例代码sn-p:

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

【讨论】:

以上是关于使用 Knockoutjs ObservableArray 确定添加或删除了哪个元素的主要内容,如果未能解决你的问题,请参考以下文章

Knockoutjs之observable和applyBindings的使用

Knockoutjs之observable和applyBindings的使用

使用 KnockoutJS 创建可重用组件

KnockoutJS + My97DatePicker

KnockoutJS数组比较算法解析

Knockoutjs 使用 MVC 从服务器填充数据