Reputation: 81
I am running into an issue where I'm adding to a collection, CollectionA
, where CollectionA
and CollectionB
are listening for an add event. However, an add event is triggered for both collections when adding to CollectionA
. CollectionA
and CollectionB
are basic collections that extend Backbone.Collection
and only setting a url.
View Definitions
ModelViewA = Backbone.View.extend({
...
render : function() {
var self = this;
var attributes = this.model.toJSON();
this.$el.html(this.template(attributes));
var collectionB = new CollectionB();
var collectionViewB = new CollectionViewB();
collectionB.fetch({
self.$el.append(collectionViewB.render().el);
});
return this;
},
...
});
CollectionViewA = Backbone.View.extend({
initialize : function() {
this.collection.on('add', this.renderOne, this);
},
...
render : function() {
this.collection.forEach(this.renderOne, this);
return this;
},
renderOne : function(model) {
console.log('Added to Collection A');
var view = new ViewA({ model : model });
this.$el.append(view.render().el);
return this;
}
});
CollectionViewB = Backbone.View.extend({
initialize : function() {
this.collection.on('add', this.renderOne, this);
},
...
render : function() {
this.collection.forEach(this.renderOne, this);
return this;
},
renderOne : function(model) {
console.log('Added to Collection B');
var view = new ViewB({ model : model });
this.$el.append(view.render().el);
return this;
}
});
Here's how I'm starting off the cascade of these events...
var collectionA = new CollectionA();
var modelViewA = new ModelViewA({
model : collectionA.at('some id');
});
$('body').append(modelViewA.render().el);
$('body').empty();
var collectionViewA = new CollectionViewA({ collection: collectionA });
$('body').append(collectionViewA.render().el);
collectionViewA.add([{...}]);
This code will output the initial view correctly with the modelView. Then it will properly render the collectionViewA
, however when I trigger the add event it will try to add to CollectionA
and CollectionB
so the console will show the following for each time the add event is called
Added to Collection B
Added to Collection A
It will also attempt to render Collection B
, but throws an error because the template is not given a model.
Let me know if this is way too confusing and I can try to flush out this description a bit more.
THANKS!
Upvotes: 4
Views: 704
Reputation: 7141
Why, in your render method of ModelViewA
, do you create a CollectionB
instance that fetches?
var collectionB = new CollectionB();
var collectionViewB = new CollectionViewB();
collectionB.fetch({
self.$el.append(collectionViewB.render().el);
});
That doesn't even parse. Are you sure you didn't accidentally edit out the anonymous success function? First let me suppose that's not quite what your code shows. That is, is it supposed to be something like:
collectionB.fetch({
success: function(){
self.$el.append(collectionViewB.render().el);
}
});
?
Let's go with that.
So when the ModelViewA
is rendered, obviously collectionB
is going to fetch something and then collectionViewB
is going to render because that's what you told it to do. Now would cause you to render ModelViewA
s?
CollectionViewA = Backbone.View.extend({
initialize : function() {
this.collection.on('add', this.renderOne, this);
}, ...
renderOne : function(model) {
console.log('Added to Collection A');
var view = new ViewA({ model : model });
this.$el.append(view.render().el);
return this;
}
what's this ViewA
? could that also refer to ModelViewA
?
If so, we might guess as to what is happening:
Your CollectionViewA
instance renders a ModelViewA
instance on every addition. Every rendering of a a ModelViewA
instance creates a CollectionB
instance (collectionB
) and a CollectionViewB
instance (collectionViewB
), and the collectionB
fetch has a success method which renders collectionViewB
. If collectionB
has any models, for every model, it successfully logs to the console "Added to Collection B" before attempting to render ViewB instances, which, if I understand you correctly, fail (which might be why you only have one "Added to Collection B" message.
Now as to why the console logs are in reverse order... I'm still trying to figure that one out. Maybe I missed something.
In any case... This situation is not ideal. I'm not sure what I could say to improve your code, though. Calling fetch
from render
seems to me like you're specifying to much to do in your render code. I'm not even sure you knew that fetch
was there to begin with.
Upvotes: 1