Javascript 寻找一种更有效的方法来设置和更改顺序主干模型属性

Javascript 寻找一种更有效的方法来设置和更改顺序主干模型属性,javascript,backbone.js,underscore.js,Javascript,Backbone.js,Underscore.js,使用Backbone.js,我创建了一个由产品模型组成的产品集合。每个产品模型都包含orderIndex属性。集合正在使用此orderIndex属性作为其比较器 在我的应用程序运行期间,我需要更改集合中某个产品的orderIndex值。在执行此操作时,我还需要调整集合中其他模型的orderIndex,以便它们仍然保持顺序。例如,如果我从四个模型开始: A -> orderIndex = 0 B -> orderIndex = 1 C -> orderIndex = 2 D -&

使用Backbone.js,我创建了一个由产品模型组成的产品集合。每个产品模型都包含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
使用原始设置的另一个示例是,如果我将orderIndex的A更改为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属性将更改为的值

有人能推荐一种更好的方法来实现这一点吗?

我通常发现,在这种情况下,“老一套”很有帮助。然后,您可以使用数组的自然顺序来更新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"]
还有一个演示