[英]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.