I believe my problem relates to scope somehow, as I'm a js newbie. I have a tiny backbone.js example where all I am trying to do is print out a list of items fetched from the server.
$(function(){
// = Models =
// Video
window.Video = Backbone.Model.extend({
defaults: function() {
return {
title: 'No title',
description: 'No description'
};
},
urlRoot: 'api/v1/video/'
});
// VideoList Collection
// To be extended for Asset Manager and Search later...
window.VideoList = Backbone.Collection.extend({
model: Video,
url: 'api/v1/video/'
});
// = Views =
window.VideoListView = Backbone.View.extend({
tagName: 'ul',
render: function(eventName) {
$(this.el).html("");
_.each(this.model.models, function(video) {
$(this.el).append(new VideoListRowView({model:video}).render().el);
}, this);
return this;
}
});
// VideoRow
window.VideoListRowView = Backbone.View.extend({
tagName: "li",
template: _.template("id: <%= id %>; title: <%= title %>"),
className: "asset-video-row",
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
// Router
var AppRouter = Backbone.Router.extend({
routes:{
"":"assetManager"
},
assetManager:function() {
this.assetList = new VideoList();
this.assetListView = new VideoListView({model:this.assetList});
this.assetList.fetch();
$('#content').html(this.assetListView.render().el);
}
});
var app = new AppRouter();
Backbone.history.start();
// The following works fine:
window.mylist = new VideoList();
window.mylistview = new VideoListView({model:window.mylist});
});
If I access mylist.fetch(); mylist.toJSON()
mylist.fetch(); mylist.toJSON()
from the console, mylist populates fine. I can tell that this.assetList.fetch()
is accurately fetching the data from the backend, but it doesn't appear to be adding the objects to this.assetList
.
The fetch
method on Backbone collections is asynchronous:
Fetch the default set of models for this collection from the server, resetting the collection when they arrive. [...] Delegates to Backbone.sync under the covers, for custom persistence strategies.
And Backbone.sync says:
Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses
(jQuery/Zepto).ajax
to make a RESTful JSON request.
So fetch
involves an (asynchronous) AJAX call and that means that you're trying to use the collection before fetch
has retrieved the data from the server. Note that fetch supports success
and error
callbacks so you can do this instead:
var self = this;
this.assetList.fetch({
success: function(collection, response) {
$('#content').html(self.assetListView.render().el);
}
});
Or you could bind a callback to the collection's reset
event as fetch
will reset the collection. Then render your assetListView
when the collection's reset
event is triggered.
Also, your assetList
is a collection so you should be doing:
this.assetListView = new VideoListView({collection: this.assetList});
and:
window.VideoListView = Backbone.View.extend({
tagName: 'ul',
render: function(eventName) {
$(this.el).html("");
_.each(this.collection.models, function(video) {
// ...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.