Kev*_*ish 16 javascript backbone.js underscore.js
说我有这些Backbone.js模型:
var Truck = Backbone.Model.extend({});
var truck1 = new Truck();
var truck2 = new Truck();
truck1.set("brand", "Ford");
truck2.set("brand", "Toyota");
truck3.set("brand", "Honda");
truck4.set("brand", "Ford");
Run Code Online (Sandbox Code Playgroud)
然后,假设我们有一个Backbone.js集合:
var TruckList = Backbone.Collection.extend({
model: Truck,
comparator: function(truck) {
return truck.get("brand");
};
});
Run Code Online (Sandbox Code Playgroud)
我是汽车收藏家,所以有时间将每辆车添加到我的收藏中:
Trucks = new TruckList();
Trucks.add(truck1);
Trucks.add(truck2);
Trucks.add(truck3);
Trucks.add(truck4);
Run Code Online (Sandbox Code Playgroud)
只关注品牌属性,truck4是truck1的副本.我的收藏中不能有重复项.我需要我的收藏品具有独特的价值观.
我的问题是,如何从Backbone.js集合中删除重复的项目?
我应该使用Underscore.js吗?如果是这样,有人可以提供一个工作/可运行的如何执行此操作的示例.
假设如下:
1.Collection没有排序
必须对品牌属性值进行删除
Ajax调用填充Truck的每个实例.这意味着在添加到集合时,您无权访问Truck属性.
Pet*_*ons 19
我会覆盖add您的TruckList集合中的方法,并使用下划线检测那里的重复项并拒绝重复.就像是.
TruckList.prototype.add = function(truck) {
// Using isDupe routine from @Bill Eisenhauer's answer
var isDupe = this.any(function(_truck) {
return _truck.get('brand') === truck.get('brand');
});
// Up to you either return false or throw an exception or silently ignore
// NOTE: DEFAULT functionality of adding duplicate to collection is to IGNORE and RETURN. Returning false here is unexpected. ALSO, this doesn't support the merge: true flag.
// Return result of prototype.add to ensure default functionality of .add is maintained.
return isDupe ? false : Backbone.Collection.prototype.add.call(this, truck);
}
Run Code Online (Sandbox Code Playgroud)
小智 7
实现此目的的最简单方法是确保您添加的模型具有唯一ID.默认情况下,Backbone集合不会添加具有重复ID的模型.
test('Collection should not add duplicate models', 1, function() {
var model1 = {
id: "1234"
};
var model2 = {
id: "1234"
};
this.collection.add([model1, model2]);
equal(1, this.collection.length, "collection length should be one when trying to add two duplicate models");
});
Run Code Online (Sandbox Code Playgroud)
试试这个.它使用任何下划线方法来检测潜在的重复,然后转出(如果是这样).当然,你可能想要打扮一下,除了更强大之外:
TruckList.prototype.add = function(newTruck) {
var isDupe = this.any(function(truck) {
return truck.get('brand') === newTruck.get('brand');
}
if (isDupe) return;
Backbone.Collection.prototype.add.call(this, truck);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我可能会在卡车上写一个函数来进行欺骗检查,这样集合就不会对这种情况了解太多.
var TruckList = Backbone.Collection.extend({
model : Truck,
// Using @Peter Lyons' answer
add : function(truck) {
// Using isDupe routine from @Bill Eisenhauer's answer
var isDupe = this.any(function(_truck) {
return _truck.get('brand') === truck.get('brand');
});
if (isDupe) {
// Up to you either return false or throw an exception or silently
// ignore
return false;
}
Backbone.Collection.prototype.add.call(this, truck);
},
comparator : function(truck) {
return truck.get("brand");
} });
Run Code Online (Sandbox Code Playgroud)
VassilisB的答案很有效,但它会覆盖Backbone Collection的add()行为.因此,当您尝试执行此操作时可能会出现错误:
var truckList = new TruckList([{brand: 'Ford'}, {brand: 'Toyota'}]);
Run Code Online (Sandbox Code Playgroud)
所以,我添加了一些检查以避免这些错误:
var TruckList = Backbone.Collection.extend({
model : Truck,
// Using @Peter Lyons' answer
add : function(trucks) {
// For array
trucks = _.isArray(trucks) ? trucks.slice() : [trucks]; //From backbone code itself
for (i = 0, length = trucks.length; i < length; i++) {
var truck = ((trucks[i] instanceof this.model) ? trucks[i] : new this.model(trucks[i] )); // Create a model if it's a JS object
// Using isDupe routine from @Bill Eisenhauer's answer
var isDupe = this.any(function(_truck) {
return _truck.get('brand') === truck.get('brand');
});
if (isDupe) {
// Up to you either return false or throw an exception or silently
// ignore
return false;
}
Backbone.Collection.prototype.add.call(this, truck);
}
},
comparator : function(truck) {
return truck.get("brand");
}});
Run Code Online (Sandbox Code Playgroud)
Underscore.js 是backbone.js 的先决条件,为此提供了一个函数: http: //documentcloud.github.com/underscore/#uniq
例子:
_.uniq([1,1,1,1,1,2,3,4,5]); // returns [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)