Updating a model with a lot of attributes (backbone.js)

I have a page containing a list of productListView images of a productView . productListView bound to the productList collection containing product models. When you click an image, a modal ModalView appears, containing more detailed information about the product that the photo was clicked on.

Problem:. To minimize the data passed to the user, only a few product attributes were fetch 'ed at page load and productListView . How to update a product model with a lot of attributes (for example, a very long description) when its photo is productListView in productListView ?

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 ) ) ); }, }); 

UPDATE

I get an Uncaught TypeError: Object [object Window] has no method 'render' error message Uncaught TypeError: Object [object Window] has no method 'render' . Why is this the case though I use _.bindAll to bind render ? I know that var self=this will work, but why not _.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(); } }); 
+4
source share
2 answers

If your Product.fetch call gets the full model (with extended attributes), modify showModal to do this, 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 doesn't get you everything, replace the fetch with an ajax call that does.

As for the update: this in the success context of the callback is window . Instead, you want to use the saved self .

+1
source

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(); } }); 
+1
source

Source: https://habr.com/ru/post/1432323/


All Articles