Reputation: 63599
I have a page containing a list productListView
of images productView
. productListView
is binded to the collection productList
containing models product
. When an image is clicked, a modal ModalView
appears containing more details about the product whose photo has been clicked on.
Problem: In order to minimize the data transferred to the user, only a few attributes of the products were fetch
'ed when the page and productListView
loaded. How should I update the model product
with more attributese (like really long description) when its photo within productListView
is clicked?
Model
Product = Backbone.Model.extend({
url: '/api/product' // Gets FULL details of product
});
Collection
ProductCollection = Backbone.Collection.extend({
url: '/api/products' // Gets MINIMAL details of product
})
View
ProductListView = Backbone.View.extend({
el: '#photo_list',
initialize: function() {
this.collection.bind('reset', this.render, this);
},
render: function() {
this.collection.each(function(photo, index) {
$(this.el).append(new ProductView({ model: photo }).render().el);
}
return this;
},
});
ProductView = Backbone.View.extend({
tagNAme: 'div',
template: _.template( $('#tpl_ProductView').html() ),
events: {
'click .photo': 'showModal',
},
render: function() {
$(this.el).html( this.template( this.model.toJSON() ) );
return this;
},
// Creates the Modal View with FULL details of the product
showModal: function() {
modalView = new ModalView({ model: this.model });
}
});
Modal View
ModalView = Backbone.View.extend({
el: $('#modal'),
template: _.template( $('#tpl_modal').html() ),
initialize: function() {
this.render();
},
render: function() {
$(this.el).show().append( this.template( this.model.toJSON( this.model ) ) );
},
});
I am getting the error Uncaught TypeError: Object [object Window] has no method 'render'
. Why is this so even though I am using _.bindAll
to bind render
? I know var self=this
will work, but why not the _.bindAll
?
initialize: function() {
_.bindAll(this, 'render');
var self = this;
// Update Model with Full details
this.model.fetch({
data: {post_id: this.model.get('id')},
processData: true,
success: function() {
// The usual renders
this.render();
}
});
Upvotes: 4
Views: 878
Reputation: 19821
In this code, you should use self.render();
instead of this.render()
initialize: function() {
_.bindAll(this, 'render');
var self = this;
// Update Model with Full details
this.model.fetch({
data: {post_id: this.model.get('id')},
processData: true,
success: function() {
// The usual renders
self.render();
}
});
Upvotes: 1
Reputation: 13105
If your Product.fetch
call gets the full model (with the extended attributes) then change showModal
to do just that and then render:
showModal: function() {
var modalView = new ModalView({ model: this.model }),
p = this.model.fetch();
p.done(modalView.render);
}
and
ModalView = Backbone.View.extend({
el: $('#modal'),
template: _.template( $('#tpl_modal').html() ),
render: function() {
this.$el.show().append( this.template( this.model.toJSON() ) );
},
});
If fetch does not get you everything, then replace the fetch with the ajax call that does.
With regards to you update: this
in the success
callback context is the window
. You want to use the saved self
instead.
Upvotes: 1