Backbone.js fires twice in add assembly

I am working with the Todos example application bundled with the latest version of Backbone (0.9.2), studying Backbone.js. My question is: why is the application designed to trigger a rendering event twice when adding a model to the Todos collection?

If I put this line in the TodoView rendering function:

// Re-render the titles of the todo item. render: function() { console.log("Rendering!"); this.$el.html(this.template(this.model.toJSON())); 

Then "Rendering!" appears twice in the console. I understand this is due to the fact that the view binds the model change event to the view rendering:

 initialize: function() { this.model.bind('change', this.render, this); 

And the render is called in addOne, which is bound to the Todos add event:

 addOne: function(todo) { var view = new TodoView({model: todo}); this.$("#todo-list").append(view.render().el); }, 

But is this a standard practice for dual rendering design? It seems like the presentation should be done when creating (or entering the DOM), and then again if the base model changes. In this case, nothing changes, but the render is called twice.

Again, I'm just learning Backbone, so I might have a major misunderstanding that leads to my confusion.

+8
javascript
source share
2 answers

Hm, looked quickly. You are right that this is happening, and this is not standard practice. The reason is a bit unclear, so bear with me;)

The todo application uses base-localstorage. When you try to add a new element to the application, it calls:

 createOnEnter: function(e) { if (e.keyCode != 13) return; if (!this.input.val()) return; Todos.create({title: this.input.val()}); this.input.val(''); }, 

Check out Todos.create . Usually create will add the model to the collection and also save it to the server. Thus, the add event will occur. This happens, although the -localstorage reference does the following on create :

 create: function(model) { if (!model.id) model.set(model.idAttribute, guid()); this.data[model.id] = model; this.save(); return model; }, 

Pay attention to model.set to give the model an id. This is what triggers the (second) change event.

You can stop this by changing the creation:

if (!model.id) model.id = guid();

+5
source share

Re-rendering should not happen.

Try debugging a little more. Try attaching the change event to the wrapper method, for example:

 initialize: function(){ this.model.bind( "change", this.renderWrapper, this ); }, renderWrapper: function(){ console.log( "in the renderWrapper" ); this.render(); } 

To ensure that the second render() was created to bind the change event, and not for another reason.

+1
source share

All Articles