跟踪列表在knockoutjs中重叠

时间:2012-04-03 23:04:24

标签: knockout.js

我有一个应用程序,其中对象可能位于多个列表中的一个列表中。一个列表的UI需要将每个项目标记为位于其中一个其他列表中。

我实施的内容的简化版本是:

function Item(id, panel) {
    var that = this;
    this.id = id;
    this.viewModel = panel;
    this.isSelected = ko.computed(function(){
        return panel.isSelected(that);
    });
}

function Panel() {
    var that = this;

    //my two lists
    this.all = ko.observableArray();
    this.selected = ko.observableArray();

    this.isSelected = function(item){
        return _(that.selected()).find(function(thing){
            console.log("iterating");
            return thing.id == item.id;
        });
    };
}

var panel = new Panel();
ko.applyBindings(panel);

//add some things to the list
for(var i=0; i<40; i++){
    var item = new Item(i, panel)
    panel.all.push(item);
    //let's select some of them. note it's actually a different object
    if (i % 2 == 0){
        panel.selected.push(new Item(i, panel));
    }
};
​

小提琴在这里:http://jsfiddle.net/89j52/5/

因此,除了给项目提供参考的奇怪之外,它也表现得非常糟糕。这是因为每次您向选定列表添加另一个项目时,它会重新计算所有项目的选定状态;注意它打印“迭代”的次数。我理解为什么会这样做,但这很痛苦。

现在显然,每次添加时, 都不需要检查每个项目。例如,我可以为项目存储查找表,然后在将某些内容添加到所选列表时更新正确的查找表。但我不确定如何将其与Knockout的可观察/计算内容相结合,并使UI更新无缝。我应该如何在Knockout的习语中解决这个问题?

1 个答案:

答案 0 :(得分:1)

如果您将 isSelected 转换为常规可观察(未计算)并在每次将项目添加到所选列表时直接更新,该怎么办:

function select(item){
    panel.selected.push(item);
    var itemInAll = _(panel.all()).find(function(thing){
        return thing.id === item.id;
    });
    itemInAll.isSelected(true);
}

不是很优雅,但绝对更有效率。您也不需要在 Item 中保留对 panel 的引用。以下是完整代码:http://jsfiddle.net/89j52/9/