Reputation: 16491
Learning Backbone at the moment and currently at a very basic level, I have set up a model, view and collection
relating to person data and want to template this data out using Handlebars. So I've created my Person Model with default values, created a People Collection that listens for the Person Collection and my Person View which should output my model data
. At the moment however only my default data is being output so I guess I'm doing something wrong. If anyone could offer any advice at all that would be great!
JS
//Model
var Person = Backbone.Model.extend({
//Default Attributes
defaults: {
'name': 'Joe',
'age': 29,
'gender': 'male',
'country': 'UK'
}
});
//Instantiate the Person Model
var person = new Person();
//Create People Collection to hold multiple Person Models
var PeopleCollection = Backbone.Collection.extend({
model: Person
});
//Add multiple Person Models into People Collection, check out the [] as this is content in JSON style
var peopleCollection = new PeopleCollection([
{
'name': 'James',
'age': 34,
'gender': 'male',
'country': 'USA'
},
{
'name': 'Jason',
'age': 31,
'gender': 'male',
'country': 'Australia'
}
]);
//View
var PersonView = Backbone.View.extend({
// tagName: '',
//Get the template markup
template: $('#person-template').html(),
initialize: function() {
this.$el.personCtn = $('#person-ctn');
// console.log('His name is ' + this.model.get('name') );
console.log(this.model);
this.render();
},
render: function() {
//Compile this.template === #person-template
var template = Handlebars.compile(this.template);
//Actually add to page
this.$el.personCtn.html( template( this.model.toJSON() ) );
return this;
}
});
//Instantiate the Person View
var personView = new PersonView({
'model': person
});
Link to demo http://jsbin.com/oFIxizuq/6/edit?html,js,output
Upvotes: 1
Views: 56
Reputation: 2661
The problem is you are passing the person
model to your view, which was created with default values when you called the following code:
// A Person model with default values
var person = new Person();
// You then pass the person model to the PersonView
var personView = new PersonView({
'model': person
});
I believe you meant to pass the peopleCollection
to the Backbone.View
. Which would look like:
//Instantiate the Person View
var personView = new PersonView({
collection: peopleCollection
});
But maybe since it's a collection we will it call it peopleView
.
//View
var PeopleView = Backbone.View.extend({
//Get the template markup
template: $('#person-template').html(),
render: function() {
var template = Handlebars.compile(this.template);
var view = this;
// render each model with the template
this.collection.each(function(model) {
view.$el.append(template(model.toJSON()));
});
return this;
}
});
// Create the view and pass the peopleCollection
var peopleView = new PeopleView({
collection: peopleCollection
});
A fiddle from your example: http://jsbin.com/oFIxizuq/8/edit
Some side suggestions:
Instead of this.$el.personCtn = $('#person-ctn')
you should assign an el
property to
your view (if you know the element exists) when you are instantiate or extend
the view, so new PeopleView({el:'#person-ctn'});
would be one way. Then within the view you can access that element using this.$el
.
You can move the Handlebars.compile
into the template
property. such as, template:Handlebars.compile($('#person-template').html())
So another way to use your code if you want to supply an el
property is:
var PeopleView = Backbone.View.extend({
el:'#person-ctn',
template: Handlebars.compile($('#person-template').html()),
render: function() {
var view = this;
this.collection.each(function(model) {
view.$el.append(view.template(model.toJSON()));
});
return this;
}
});
var peopleView = new PeopleView({
collection: peopleCollection
});
peopleView.render();
Guess I can add that example for you as well http://jsbin.com/opuroNO/1/edit
Upvotes: 2
Reputation: 35973
I have change the logic of your app, well, in your app there are some problem. You don't use collection.
To use collection you need to add elements by default like a model.
Other problem you print the model not the collection and you print always a line because using html() you override always your html.
this is the solution that I have create for you. It works fine for me.
try please:
//Model
var Person = Backbone.Model.extend({
//Default Attributes
defaults: {
'name': 'Joe',
'age': 29,
'gender': 'male',
'country': 'UK'
}
});
//Create People Collection to hold multiple Person Models
var PeopleCollection = Backbone.Collection.extend({
model: Person,
addPerson: function(elements, options) {
return this.add(elements, options);
}
});
//View
var PersonView = Backbone.View.extend({
// tagName: '',
//Get the template markup
template: $('#person-template').html(),
initialize: function() {
this.collection = new PeopleCollection([],{ });
var p = { name: 'James',age: 34, gender: 'male' , country: 'USA'};
var p2 = { name: 'Jason',age: 31, gender: 'male' , country: 'Australia'};
this.elementModel = new Person(p);
this.collection.addPerson(this.elementModel);
this.elementModel = new Person(p2);
this.collection.addPerson(this.elementModel);
this.$el.personCtn = $('#person-ctn');
// console.log('His name is ' + this.model.get('name') );
console.log(this.collection);
this.render();
},
render: function() {
//Compile this.template === #person-template
var template = Handlebars.compile(this.template);
var here = this;
//Actually add to page
$.each( this.collection.models , function( key, value ) {
console.log(value);
here.$el.personCtn.append( template( value.toJSON() ) );
});
return this;
}
});
//Instantiate the Person View
var personView = new PersonView({
});
Upvotes: 0