I´m new to Backbone.js, but after some research I still couldn´t find the source of my problem.
I am developing an App and I have a collection of models, which I eventually want to display in a view (just one model at a time).
Here´s my code so far:
var App = {
Item: Backbone.Model.extend({
defaults: function() {
return {
id: -1,
name: '',
imageReference: '',
itemTags: []
};
},
sync: function() { return null; },
fetch: function() { return null; },
save: function() { return null; }
}),
Items: Backbone.Collection.extend({
model: this.Item,
}),
ItemView: Backbone.View.extend({
el: "#itemdiv",
tagName: "<div>",
className: "item",
template: _.template($("#template-item-view").html()),
initialize: function(model) {
this.model = model;
this.listenTo(this.model, "change", this.render);
this.render();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
})
};
var items = new App.Items();
items.add(new App.Item({name: "iPhone", id: 1, imageReference: "iPhone.jpg", ["mobile", "smartphone"]}));
items.add(new App.Item({name: "MacBook", id: 2, imageReference: "MacBook.jpg", ["laptop", "computer"]}));
All of the above works. When I inspect items
it has the two models including the parameters. But when I try to add a new item directly to the Collection with Collection.create()
like:
items.create({name: "Apple Watch", id: 3, imageReference: "AppleWatch.jpg", ["watch", "redundant"]});
it throws an error:
TypeError: undefined is not a constructor (evaluating 'new this.model(attrs, options)')
In case it helps, this error appears in Backbone.js in line 915 (dev version), the wrapping function is
/* from Backbone.js, Dev-Version, Line 911-919 */
_prepareModel: function(attrs, options) {
if (attrs instanceof Model) return attrs;
options = options ? _.clone(options) : {};
options.collection = this;
var model = new this.model(attrs, options);
if (!model.validationError) return model;
this.trigger('invalid', this, model.validationError, options);
return false;
}
I can´t figure out if that is just a small bug or if something with my architecture is wrong. Am very thankful for help and also on comments towards best practices, etc.
Thanks in advance!
You have an error in your add lines:
items.add(new App.Item({name: "iPhone", id: 1, imageReference: "iPhone.jpg", ["mobile", "smartphone"]}));
items.add(new App.Item({name: "MacBook", id: 2, imageReference: "MacBook.jpg", ["laptop", "computer"]}));
Should be:
items.add(new App.Item({name: "iPhone", id: 1, imageReference: "iPhone.jpg", itemTags: ["mobile", "smartphone"]}));
items.add(new App.Item({name: "MacBook", id: 2, imageReference: "MacBook.jpg", itemTags: ["laptop", "computer"]}));
The field itemTags
was missing. Does that fix it?
The point at which the following is run:
Items: Backbone.Collection.extend({
model: this.Item,
}),
this
isn't known.
So if you're namespacing to encapsulate your code do one of either:
var App = {}
App.item = Backbone.Model.extend({...})
App.items = Backbone.Collection.extend({...})
App.itemView = Backbone.View.extend({...})
App.items.add({})
App.items.add({})
Or:
(function() {
var item = Backbone.Model.extend({...})
var items = Backbone.Collection.extend({...})
var itemView = Backbone.View.extend({...})
var items.add({})
var items.add({})
})()