I am new in Backbone.js and I keep failing to understand how the model and the view are connected.
I played with Angular where things are pretty clear there, how model, view and controller are connected.
I know Angular and Backbone are different and the latter is MV*.
In Backbone I can understand how model and view are created and work, but how are they connected? Seems to me they are seperated.
Please take a minute to explain or point me to a tutorial.
Thanks in advance
EDIT
OK, here is an example. It happens that I read the book that trolle suggests. This is a code from the book's github
I start reading. I understand the Todo model. I understand the TodoList collection. Then I get to the TodoView
creates a new li
uses Underscore template to compile html
defines some functions that imlements later in the same view
defines an initialize function
inside that function
what is this? this.model.bind('change', this.render, this);
how he can magically bind the action change to a model? How the code knows about the model? When he defined the model and how? Just because is there, the code knows that model = Todo model?
How does he do that bind? What am I missing.
This confuses me, so reading AppView view does not help me much
Thanks again
In backbone.js views are used for displaying models in browser.
For example you can have a model object, whose JSON representation resembles the following: {'firstName': 'foo', 'lastName': 'bar' }
And you use view object to map this model to browser DOM.
As a rule, you use view object along with certain template engine.
Templates allows for creating html chunks filled with model's data.
If you are using underscore template function, your template may look something like this:
<div>
<div>First Name: <%= firstName %></div>
<div>Last Name: <%= lastName%></div>
</div>
After merging template with model's data it would be:
<div>
<div>First Name: foo</div>
<div>Last Name: bar</div>
</div>
You can reuse this view object and its template to display another model object, for example {'firstName':'another foo', 'lastName':'another bar'}, so that the result html would be:
<div>
<div>First Name: another foo</div>
<div>Last Name: another bar</div>
</div>
That is one thing about connection between model and view.
Also view object can listen to changes in your model object to render immediately last updates. For example (inside view object):
initialize: function() {this.listenTo(this.model, 'change', this.render);}
In short, views are the logic behind the presentation of the model's data to the user. So in its simplest form, you bind a model to a view through the models change events, so you can update the presentation instantly whenever your data changes. So a simple view would take in a model, create HTML elements based on that models data, insert that html into the DOM and update that HTML whenever the data changes.
You can find a great book full of helpful examples here (free): http://addyosmani.github.io/backbone-fundamentals/
EDIT:
With regards to your updated question about how the view knows about the model, this.model is a reference to the actual model object. You can set the reference to the model when you create the view. That is, when you call your view-constructor to instantiate a view, you could pass in a model. You need to go all the way into the AppView object in the code example to see where this happens, in the addOne method:
addOne: function(todo) {
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
}
The function gets a model as a parameter, and when the view is instantiated that model is referenced. So now you have a view that knows about the model, and when the view.render method is called, the view can render it's template with the model data. When you change the data in the model, for instance by using the set method, myModel.set({title: "March 20", content: "In his eyes she eclipses..."});, you trigger the change event for that model. You can see all the built in events for backbone here: http://backbonejs.org/#Events-catalog. The view is listening for that event, just like it could listen for a click event or any other event. In the code in your example the view listenes for a change event from the model. If it hears it it knows that the object behind this.model has changed, and it can then update the DOM with the new data or do something else. In the case of the example it calls this.render, which updates the DOM with the new model data.
I think you want to know about Backbone.Events (http://backbonejs.org/#Events), both Models and Views make use of this module and that's how the view learns about changes in the Model, if you want to learn how this is implemented you can always read the annotated source (http://backbonejs.org/docs/backbone.html#section-19), but more important I think you want to learn about the observer pattern: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript.
i am trying to learn backbone.js
trying to get data from php then display it by model, view and route of backbone.js
but its not displaying my data, it displaying [object Object]
you can see output here::
http://php-backbone.gopagoda.com/
and the source code::
https://github.com/foysal-mamun/php-backbone
i have console.log my this.model, you can see my data in::
this.model.attributes.message
please help me how can i fix this.
Thanks.
Change like below in your router.
this.messageModel.fetch({success: function () {
$('#msg').html(this.messageView.render().el);
}}
and change like below in your render function.
$(this.el).html(this.template(this.model.attributes));
I have a Collection called Projects that contains several models of type Project. When I want to list all the projects, I use a ListProjectsView. Its render function generates a ProjectView for each project in the collection, making it possible to delete one single project by binding an event to its name.
However, now I want to use Handlebars for creating templates. With handlebars it easier to display all the collection models, with the each helper, like this:
<ul>
{{#each projects}}
<li>{{this.name}}</li>
{{/each}}
</ul>
This works fine but now I am wondering how can I delete one project, since I am not using ProjectView anymore. Do I need to add an id to each <li> so I can bind an event? Or do I have to use ProjectView to do this?
Thanks in advance.
the logic here will have to run through ListProjectsView. One way is to do as you say and attach an data-id to each li and then in your event handler get the target
deleteProjectHandler : function(evt){
var $target = $(evt.target), id = $target.data('id');
this.deleteProject(id);
}
Or something of the like.
I wanted to get attributes from model. I tried
this.model.get("group_description") and
this.model.models.get("group_description")
But none of them seem to work any help ? Below is snapshot of model structure...
your object d (this) is a Backbone.Collection, so you want
this.at(0).get("group_description")
Backbone Model.save doesn't wrap model state to nested object. Is it normal?
Typical scenario for Rails is something like this params[:product]. How could I achieve this?
This was answered previously: Saving nested objects with Rails, backbone.js, and accepts_nested_attributes_for
I would suggest to override toJSON on the backbone model.
toJSON: function(){
json = {car : this.attributes};
return _.extend(json, {engine_attributes: this.get("engine").toJSON());
}
toJSON is called within the sync method just before sending data to the backend.