Reputation: 772
I can't seem to get JSON that is loading into my FriendsCollection to render into FriendListView. I can see that it is loading through the network panel, and I can log the data to the console, but for some reason the fetch command isn't passing the data to the view to be rendered.
I'm using Backbone 1.0.
The code i'm using is available on jsbin here: http://jsbin.com/OHePaki/1/edit?html,js,output
// MODELS
var ArtifactModel = Backbone.Model.extend({
initialize: function() {
this.on('reset', function(){ artifactView.render() })
},
defaults: {
"text": "Unknown Text",
"timestamp": "Unknown timestamp"
}
});
var artifactModel = new ArtifactModel();
// COLLECTIONS
var ArtifactCollection = Backbone.Collection.extend({
model: ArtifactModel,
url: '/getDigest.json',
// url: 'http://we365.local/Artifact/GetShareableArtifact?token=b88d2640826bb8593f6edb308ce604f28225f240&artifact_id=2&social_site=tw&log_inside=&go',
parse: function(data) {
console.log('running parse');
return _.map(data.response.content, _.identity);
},
initialize: function(){
this.on('reset', function(){ artifactListView.render(); }),
console.log('running init function for ArtifactCollection');
this.fetch();
//this.reset(artifactjson, { parse: true });
console.log(this.toJSON());
}
});
var artifactCollection = new ArtifactCollection();
// VIEWS
var ArtifactView = Backbone.View.extend({
tagName: 'li',
className: 'single-model',
render: function(){
var template = Handlebars.compile($('#stream_getDigest').html());
this.$el.html(template(this.model.toJSON()));
return this;
}
});
var ArtifactListView = Backbone.View.extend({
initalize: function(){
this.collection.on('add', this.addOne, this);
},
render: function(){
this.collection.forEach(this.addOne, this);
},
addOne: function(artifactModel){
var artifactView = new ArtifactView({model: artifactModel});
this.$el.append(artifactView.render().el);
}
});
// rendering
var artifactView = new ArtifactView({model: artifactModel});
var artifactListView = new ArtifactListView({collection: artifactCollection});
artifactView.render();
artifactListView.render();
$('#list').html(artifactListView.$el.html());
Upvotes: 1
Views: 1281
Reputation: 4340
By default jQuery ajax call is asynchronous, the code will keep running without waiting for the .fetch()
to be finished. In your code the view
is rendered before the collection is ready so the data for the view
is empty.
You can pass jQuery ajax option to fetch
function so you can do the following (http://backbonejs.org/#Collection-fetch):
...
initialize: function(){
this.on('reset', function(){ artifactListView.render(); }),
console.log('running init function for ArtifactCollection');
this.fetch({async:false});
console.log(this.toJSON()); //This will log the loaded collection
}
...
Or you can change fetching strategy to take the advantage of asynchronous load:
this.fetch().done(function(){
//Things to do after collection is loaded
});
//this's not good to use in init function
Upvotes: 2
Reputation: 3454
You need to set handlers on the models. Something like this:
friendModel.on('change', function() { friendView.render(); });
friendCollection.on('change', function() { friendListView.render(); });
Or better yet, put these lines in the constructors for friendModel
and friendCollection
(see http://backbonejs.org/#View-constructor ).
Upvotes: 2