我刚开始使用backbone.js。我在从服务器获取数据时遇到问题。这是我从服务器获得的响应。
[{
"list_name":"list1",
"list_id":"4",
"created":"2011-07-07 21:21:16",
"user_id":"123456"
},
{
"list_name":"list2",
"list_id":"3",
"created":"2011-07-07 21:19:51",
"user_key":"678901"
}]
这是我的javascript代码......
// Router
App.Routers.AppRouter = Backbone.Router.extend({
routes: {
'': 'index'
},
initialize: function() {
},
index: function() {
var listCollection = new App.Collections.ListCollection();
listCollection.fetch({
success: function() {
new App.Views.ListItemView({collection: listCollection});
},
error: function() {
alert("controller: error loading lists");
}
});
}
});
// Models
var List = Backbone.Model.extend({
defaults: {
name: '',
id: ''
}
});
App.Collections.ListStore = Backbone.Collection.extend({
model: List,
url: '/lists'
});
// Initiate Application
var App = {
Collections: {},
Routers: {},
Views: {},
init: function() {
var objAppRouter = new App.Routers.AppRouter();
Backbone.history.start();
}
};
我在Backbone.js的这一行上收到错误“无法将相同的模型添加到两次”
if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
我检查了Backbone.js注释,发现第一个模型被添加到集合中,但第二个模型给出了这个错误。为什么会这样?我应该更改服务器端响应中的内容吗?
答案 0 :(得分:8)
您的List
在id
属性中有defaults
,默认情况下每个实例都具有相同的ID,Backbone正在使用它来检测欺骗。如果您的数据使用list_id
作为ID,则需要将idAttribute: 'list_id'
放在List
类定义中,以告知Backbone。
顺便说一下,我更喜欢不在对象属性中复制类型信息(Backbone.js同意这一点)。具有一致的属性名称是骨干所期望的并且更易于使用。因此,不要使用list_id
和list_name
,而只需在所有类上使用id
和name
。
答案 1 :(得分:1)
使用此修复程序添加具有相同ID的模型。
添加时,请使用:collection.add(model,{unique: false})
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Backbone.Collection = (function(_super) {
__extends(Collection, _super);
function Collection() {
return Collection.__super__.constructor.apply(this, arguments);
}
Collection.prototype.add = function(models, options) {
var i, args, length, model, existing;
var at = options && options.at;
models = _.isArray(models) ? models.slice() : [models];
// Begin by turning bare objects into model references, and preventing
// invalid models from being added.
for (i = 0, length = models.length; i < length; i++) {
if (models[i] = this._prepareModel(models[i], options)) continue;
throw new Error("Can't add an invalid model to a collection");
}
for (i = models.length - 1; i >= 0; i--) {
model = models[i];
existing = model.id != null && this._byId[model.id];
// If a duplicate is found, splice it out and optionally merge it into
// the existing model.
if (options && options.unique) {
if (existing || this._byCid[model.cid]) {
if (options && options.merge && existing) {
existing.set(model, options);
}
models.splice(i, 1);
continue;
}
}
// Listen to added models' events, and index models for lookup by
// `id` and by `cid`.
model.on('all', this._onModelEvent, this);
this._byCid[model.cid] = model;
if (model.id != null) this._byId[model.id] = model;
}
// Update `length` and splice in new models.
this.length += models.length;
args = [at != null ? at : this.models.length, 0];
Array.prototype.push.apply(args, models);
Array.prototype.splice.apply(this.models, args);
// Sort the collection if appropriate.
if (this.comparator && at == null) this.sort({silent: true});
if (options && options.silent) return this;
// Trigger `add` events.
while (model = models.shift()) {
model.trigger('add', model, this, options);
}
return this;
};
return Collection;
})(Backbone.Collection);
答案 2 :(得分:0)
Backbone阻止我们将相同的模型插入一个集合中...... 你可以在backbone.js第676行到第700行看到它
如果你真的想要将相同的模型插入到集合中,只需删除那里的代码
if(existing = this.get(model)){//here
...
}