Reputation: 542
I'm kind of new to backbone coming from knockout.js and I'm trying to get over this simple hump. I have this code:
$(function(){
window.Student = Backbone.Model;
window.Students = Backbone.Collection.extend({
model: Student,
url: 'test.php'
});
window.students = new Students();
window.AppView = Backbone.View.extend({
el: $('#container'),
initialize: function() {
Students.bind('reset', this.render);
},
render: function(){
console.log(Students.toJSON());
}
});
window.appview = new AppView();
$('#test').click(function(){
//var students = new Students();
students.fetch();
var q = students.toJSON();
console.log(q);
/*
students.create({
name: 'John',
grade: 'A'
}); */
})
});
My server sends the following JSON:
[{"id": "1233","name": "Karen","grade": "C"},{"id": "1234","name": "Susan", "grade": "F"}]
When I click the button and look at the console in Chrome, I see:
First Click:
[] - Corrected -just an empty array
Second Click:
[
Object
grade: "C"
id: "1233"
name: "Karen"
__proto__: Object
,
Object
grade: "F"
id: "1234"
name: "Susan"
__proto__: Object
]
First question is why does it take two clicks? Second: How can I simply assign/bind the grade(both as a collection and by id) to a textbox, <li>
or other UI element(better yet make it observable when ajax pops in).
Upvotes: 0
Views: 6407
Reputation: 18597
The console message you are seeing is from the click event handler. The console message from the render method never gets called.
You don't see anything in the first log message because fetch
is an asynchronous method, so when you call toJSON
right after fetch
, the collection hasn't been populated from the fetch method yet.
There are a couple changes you need to make to your code to get it work as expected.
First, you need to pass in the collection when you instantiate the view
//original
window.appview = new AppView();
//new
window.appview = new AppView({ collection: window.students });
Then within the view you need to bind to the reset event on the collection that was passed in to the constructor. (You have to bind to an instantiated object, and not the definition of an object like you were originally doing)
window.AppView = Backbone.View.extend({
el: $('#container'),
initialize: function() {
_.bindAll(this, 'render');
this.collection.bind('reset', this.render);
},
render: function(){
console.log(this.collection.toJSON());
}
});
Now comment out the console log message in your click event, then you will only have to click once, and you will see a console log message from the render method.
$('#test').click(function(){
//var students = new Students();
students.fetch();
//var q = students.toJSON();
//console.log(q);
/*
students.create({
name: 'John',
grade: 'A'
}); */
})
Upvotes: 7