【问题标题】:ko.observableArray support for associative arraysko.observableArray 支持关联数组
【发布时间】:2011-06-22 18:50:51
【问题描述】:

有没有更好的(内置的?)方法来混合 observableArray 和关联数组?

viewModel = {
    a: ko.observableArray(),
    a_assoc: {},
    add_item: function(i) {
        if (typeof this.a_assoc[i] == 'undefined') {
            this.a.push(i);
            this.a_assoc[i]=1;
        }
    }
}

viewModel.add_item('bla');

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    通常,您会在 Knockout 中执行以下操作:

    var viewModel = {
        a: ko.observableArray(["a","b","c","d"]),
        add_item: function() {
           this.a.push("new" + this.a().length);   
        }
    };
    
    viewModel.a_assoc = ko.dependentObservable(function() {
        var result = {};
        ko.utils.arrayForEach(this.a(), function(item) {
           result[item] = 1;
        });
        return result;
    }, viewModel);
    

    因此,您有一个dependentObservable,它将您的数组映射到一个对象。请注意,每次更新原始数组时,都会重建对象。因此,它比您帖子中的方法效率低,但是除非您的对象很大,否则它会导致性能问题是值得怀疑的。

    示例:http://jsfiddle.net/rniemeyer/PgceN/

    【讨论】:

    • 感谢 RPN。我的数据集将增长到 2K,所以不,我认为性能不是问题。顺便说一句,ko.utils 上有在线参考吗?
    • 目前没有 utils 的文档。目前最好的资源来自我的博客:knockmeout.net/2011/04/utility-functions-in-knockoutjs.html
    • 从那以后你有没有想出比这更通用的东西?也希望对我的(刚刚添加的)答案有任何反馈。谢谢
    【解决方案2】:

    我认为最好在底层使用关联数组来提高性能。您还(正如您所提到的)需要使用 observableArray 来跟踪更改(因为这就是淘汰赛的工作方式)。

    如果您正在寻找“淘汰友好型”关联数组,您可能需要一种方法来跟踪项目的更改(从而影响依赖链)。

    http://jsfiddle.net/rz41afLq/2/

    这是我想出的适合我需要的方法。基本上,您将键值对存储在 observableArray 中,并使用标准关联数组存储副本以供查找。

    // VIEW MODEL
    var viewModel = {
    
        // we have to use observable array to track changes
        items: ko.observableArray([]),
    
        // also use associative array for performance
        _assoc: {},
    
        update_item: function(key, value) {
    
            // use a true assoc array for performance
            // _assoc[key] = ko.observable(value)
            if (viewModel._assoc[key])
            {
                // update observable (overwriting existing item)
                viewModel._assoc[key].value(value);
            }
            else { 
                // Important: See how we wrap value with an observable to detect changes
                this.items.push(viewModel._assoc[key] = { key: key, value: ko.observable(value) });
            }
        }
    };
    

    所以你这样救你的狗:

    update_item('dogs', ['kim', 'abbey', 'goldie', 'rover']);
    update_item('dogs', ko.observableArray(['kim', 'abbey', 'goldie', 'rover']));
    

    (第二个只有在你打算在狗列表上调用pop()push()并且想要更新UI时才需要。当然你可以随时调用update_item来完全更新项目在这种情况下,它不需要是可观察的)

    要查找一个值,您可以动态创建一个计算来获取它:

    var dogs = getValue('dogs');
    

    然后,一旦关联数组中索引为“dogs”的值发生变化,那么可观察的dogs() 就会更新(并且可以链接)。这个dogs observable 当然可以绑定到 UI 上

    var getValue = function(key) { return ko.pureComputed(function() 
    {
        // reevaluate when item is added or removed to list
        // not necessary if the value itself changes
        viewModel.items();                                                      
    
        var item = viewModel._assoc[key];
        return (item == null) ? null : item.value();
    
    }, viewModel);
    

    【讨论】:

      猜你喜欢
      • 2012-03-19
      • 2011-06-26
      • 1970-01-01
      • 2018-11-07
      • 2010-09-25
      • 2013-07-01
      • 2015-05-23
      • 2017-06-22
      相关资源
      最近更新 更多