【问题标题】:Looking for a more efficient way to set and alter sequential Backbone model attributes寻找一种更有效的方法来设置和更改顺序 Backbone 模型属性
【发布时间】:2014-05-02 04:15:55
【问题描述】:

使用 Backbone.js,我创建了一个由 Product 模型组成的 Products 集合。每个Product 模型都包含一个orderIndex 属性。该集合使用此orderIndex 属性作为其比较器。

在我的应用程序运行期间,我需要更改集合中产品之一的 orderIndex 值。当我这样做时,我还需要为集合中的其他模型调整orderIndex,以便它们仍然保持顺序。例如,如果我从四个模型开始:

A -> orderIndex = 0
B -> orderIndex = 1
C -> orderIndex = 2
D -> orderIndex = 3

然后我将 B 的 orderIndex 更改为 2,然后我还希望 C 更改为 1,以便在集合上调用 sort() 时 B 和 C 交换位置:

A -> orderIndex = 0
B -> orderIndex = 2
C -> orderIndex = 1
D -> orderIndex = 3

另一个使用原始设置的示例是,如果我将 A 的 orderIndex 更改为 3,那么我还需要将 B 更改为 0,C 更改为 1,D 更改为 2,结果是:

A -> orderIndex = 3
B -> orderIndex = 0
C -> orderIndex = 1
D -> orderIndex = 2

我已经编写了一个函数来处理这个问题,但我觉得我忽略了一种更有效的方法来使用更多内置的下划线或 js 函数来执行此操作。这是我现在正在使用的功能:

adjustModelOrderIndex: function(model, newIndex){
    var currentOrderIndex = model.get("orderIndex");
    var newOrderIndex = newIndex;

    model.set({orderIndex: newOrderIndex});

    _.each(_.without(this.models, model), function(model){
        if(currentOrderIndex > newOrderIndex){
            if(model.get("orderIndex") >= newOrderIndex && model.get("orderIndex") <= currentOrderIndex){
                model.set({orderIndex: model.get("orderIndex") + 1});
            }
        }
        else{
            if(model.get("orderIndex") <= newOrderIndex && model.get("orderIndex") >= currentOrderIndex){
                model.set({orderIndex: model.get("orderIndex") - 1});
            }
        }
    }, this);

}

这个函数存在于我的集合中,参数表示要更改的模型,以及其orderIndex 属性将要更改为的值。

有人可以推荐一个更好的方法来完成这个吗?

【问题讨论】:

    标签: javascript backbone.js underscore.js


    【解决方案1】:

    我通常在raw array of models 上发现普通的旧Array.prototype.splice 在这种情况下会很有帮助。然后,您可以使用数组的自然顺序来更新您的 orderIndex 属性:

    var OrderedCollection = Backbone.Collection.extend({
        comparator: 'orderIndex',
    
        adjustModelOrderIndex: function(model, newIndex) {
            var currentOrderIndex = model.get("orderIndex");            
            if (newIndex === currentOrderIndex) return;
    
            // remove the model from the array
            this.models.splice(currentOrderIndex, 1);
    
            // reinject it at its new position
            this.models.splice(newIndex, 0, model);
    
            // update orderIndex
            this.each(function(model, ix) {
                model.set('orderIndex', ix);
            });
    
            // order changed, let's trigger a sort event
            // or use this.sort() if you prefer
            this.trigger('sort', this);
        }
    });
    

    示例用法:

    var c = new OrderedCollection([
        {id: 'D', orderIndex: 3},
        {id: 'C', orderIndex: 2},
        {id: 'B', orderIndex: 1},
        {id: 'A', orderIndex: 0}
    ]);
    // ["A", "B", "C", "D"]
    c.on('sort', function() {
        console.log(c.pluck('id'));
    });
    
    c.adjustModelOrderIndex(c.get('B'), 0); //  ["B", "A", "C", "D"]
    c.adjustModelOrderIndex(c.get('B'), 1); //  ["A", "B", "C", "D"]
    c.adjustModelOrderIndex(c.get('B'), 2); //  ["A", "C", "B", "D"]
    c.adjustModelOrderIndex(c.get('A'), 3); //  ["C", "B", "D", "A"]
    

    还有一个与http://jsfiddle.net/F6XSC/1/一起玩的演示

    【讨论】:

      猜你喜欢
      • 2023-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 2017-02-24
      相关资源
      最近更新 更多