Reputation: 257
I have a category model that has child category models (That works fine) via this code:
var ImageSetCategory = Backbone.Model.extend({
childrenCategories : new Array(),
initialize: function () {
var self = this;
if (this.has('childrenCategories')) {
$.each(this.get('childrenCategories'), function () {
var category = new ImageSetCategory(this);
self.childrenCategories.push(category);
});
}
}
});
I also have a view that uses this model and renders all the children categories. (basicly, I'm attempting to make a tree view) It loops through the child categories using jquery, instantiates a new version of its self with each child category as the model, and renders it. But I'm hitting an endless loop that constantly is trying to process the same model.
var ImageSetCategoryView = Backbone.View.extend({
tagName: 'li',
className: 'nested-category',
template: Handlebars.templates.imageSetCategoryView,
render: function() {
var self = this;
var templateHtml = this.template(this.model.toJSON());
self.$el.html(templateHtml);
// *****************************
// ENDLESS LOOP
// this is always the same model from the array
// *****************************
$.each(self.model.childrenCategories, function () {
var categoryView = new ImageSetCategoryView({ model: this });
self.$el.children('ul').append(categoryView.render().el);
});
return this;
},
});
Why is this causing an endless loop? Am I'm not following best practices? My background is C# so I'm trying to accomplish this in an OOP way.
Upvotes: 0
Views: 99
Reputation: 2050
The reason is that all instances of ImageSetCategory
share the same childrenCategories
array. This way in ImageSetCategory.initialize
function you create circular references (ImageSetCategory.childrenCategories
points to the array and ImageSetCategory.childrenCategories[0]
points to ImageSetCategory
itself). This makes $.each
in ImageSetCategoryView.render
iterate over the same model. To avoid it you should initialize array inside of ImageSetCategory.initialize
function:
var ImageSetCategory = Backbone.Model.extend({
initialize: function () {
var self = this;
this.childrenCategories = [];
if (this.has('childrenCategories')) {
$.each(this.get('childrenCategories'), function () {
var category = new ImageSetCategory(this);
self.childrenCategories.push(category);
});
}
}
});
To learn more about why this happens read about prototypes in JavaScript and how they are used to implement object-oriented paradigm.
Upvotes: 2