Backbone.js Model to View Connection
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).
felix
Updated on July 12, 2020Comments
-
felix almost 4 years
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
-
felix almost 13 yearsWhen I tried to set like {model : todo }, I got an error that bind is not defined for change.basically what gets passed is a normal object without backbone model specific methods :(
-
Factor Mystic almost 13 yearsWhere do you set
{model: todo}
, you haven't shown that bit of your code. Are you confident that thetodo
variable isn't null in that context? -
felix almost 13 yearsI have updated the question with the piece of code where the new taskview is created. no it was not null, it was an ordinary object.
-
SimplGy almost 12 yearsI'm looking for the 'right' way to do this. Should the view decide which model it is attached to or should the model decice? Who's in charge of the view<->model connection in backbone?
-
Factor Mystic almost 12 years@SimpleAsCouldBe there is no "right" way, cf backbonejs.org/#FAQ-tim-toady "Backbone.js is intended to be fairly agnostic about many common patterns in client-side code" ... "References between Models and Views can be handled several ways"
-
SimplGy almost 12 years@FactorMystic Yeah, I read that yesterday, too. In some cases, especially those closely related to framework functionality, I'd really like to see described one or several different good ways to accomplish something. ricostacruz.com/backbone-patterns is a good start at that. Maybe I should contribute.