简体   繁体   English

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

[英]Looking for a more efficient way to set and alter sequential Backbone model attributes

Using Backbone.js, I've created a Products collection made up of Product models. 使用Backbone.js的,我创建了一个Products组成的集合Product型号。 Each Product model contains an orderIndex attribute. 每个Product模型都包含一个orderIndex属性。 The collection is using this orderIndex attribute as its comparator. 集合使用此orderIndex属性作为其比较器。

During my app's operation, I need to change the orderIndex value for one of the products in the collection. 在应用程序运行期间,我需要更改集合中产品之一的orderIndex值。 When I do this, I also need to adjust the orderIndex for the other models in the collection so that they still remain in sequential order. 当我这样做时,我还需要调整orderIndex中其他模型的orderIndex ,以便它们仍然保持顺序。 As an example, if I start with four models: 例如,如果我从四个模型开始:

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

And then I change the orderIndex of B to 2, I would then also want C to change to 1, so that B and C switch places when sort() is called on the collection: 然后将B的orderIndex更改为2,然后我还希望C更改为1,以便在对集合调用sort()时B和C切换位置:

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

Another example using the original setup would be if I changed orderIndex of A to 3, then I would also need B to change to 0, C to change to 1, and D to change to 2, resulting in: 使用原始设置的另一个示例是,如果我将A的orderIndex更改为3,那么我还需要B更改为0,C更改为1,D更改为2,结果是:

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

I've written a function to handle this, but I feel like I'm overlooking a more efficient way to do this using more built in underscore or js functions. 我已经编写了一个函数来处理此问题,但是我觉得自己正在忽略使用更多内置下划线或js函数来执行此操作的更有效方法。 Here's the function I'm using now: 这是我现在正在使用的功能:

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);

}

This function lives in my collection, and the arguments represent the model that is being changed, as well as the value that its orderIndex attribute is going to be changed to. 此函数存在于我的集合中,参数表示要更改的模型以及其orderIndex属性将要更改的值。

Can someone recommend a better way to accomplish this? 有人可以推荐一种更好的方法来实现这一目标吗?

I usually find plain old Array.prototype.splice on the raw array of models to be of great help in this kind of situation. 我通常会在原始模型数组上找到普通的旧Array.prototype.splice在这种情况下有很大帮助。 You can then use the natural order of the array to update your orderIndex attributes : 然后,您可以使用数组的自然顺序来更新您的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);
    }
});

Sample usage: 用法示例:

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"]

And a demo to play with http://jsfiddle.net/F6XSC/1/ 还有一个可与http://jsfiddle.net/F6XSC/1/一起玩的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM