Javascript – Backbone.js Model to View Connection

backbone.jsjavascript

I am a Backbone.js newbie. I was just playing around with it. I would like to know whether the model is related with the View. In the provided todos example, I see in the addOne method, a new View is created and associated with the newly created model and appended.

  window.AppView = Backbone.View.extend({
     // view code
     addOne: function(todo) {
          var view = new TodoView({model: todo});
          this.$("#todo-list").append(view.render().el);
     }
  }

When I tried to do a similar thing, I got an error saying "bind method cannot be found on undefined".

window.TodoView = Backbone.View.extend({

     initialize: function() {
          _.bindAll(this, 'render', 'close');
          this.model.bind('change', this.render); // I got the error at this place. 
          this.model.view = this;
     }
});

In order to solve this, I got to pass the newly created model as a param to the view constructor and I got to do this.model = task inorder to associate it.

window.TodoView = Backbone.View.extend({

     initialize: function(task) {
          _.bindAll(this, 'render', 'close');
          this.model = task
          this.model.bind('change', this.render);// now there is no error
          this.model.view = this;
     }
});

window.AppView = Backbone.View.extend({


   insertTask:function(){
        var newTask, newTaskView;
        newTask = new Task(JSON.parse(xhr));
        Tasks.create(newTask);
        newTaskView = new TaskView({ model: newTask });
        $("#todo_list").append(newTaskView.render().el);
        this.input.val('');
}

});

But the todos example, do not have something like that. How is the new model associated with the new view implicitly in the todos example?

Thanks

Best Answer

It's not implicit at all, it's explicit in this line right here:

var view = new TodoView({model: todo});

This is creating a new TodoView view and setting its model property to the addOne function's only parameter (todo, which is a model).

Whenever a new model is added to the Todos collection, the addOne method is called with the new model as the parameter.

Todos.bind('add', this.addOne);

Then, in addOne, a new view is created for that model and the relationship is explicity set, via {model: todo}. This is what you're missing from your version of the code, I suspect.

What you appear to be attempting to do is link up the view and the model in the view's init function, and that's fine, but you're on your own if you do that- which means you need to set up the model <-> view relationship yourself (which you have solved by passing the model as a parameter to the view init function).

Related Topic