问题
I am trying to fetch a collection data from the server and load it into my collection object, with Backbone.js. I want to fetch these data at the start, and load my html page with these data. However, the data I downloaded from the server does not get populated into the collection properly. The collection length is zero, do anyone know what I am doing wrong?
(function ($) {
window.Menu = Backbone.Model.extend({});
window.MenuCollection = Backbone.Collection.extend({
model: window.Menu,
initialize: function() {
_.bindAll(this, 'parse');
},
url: function(){
return 'http://localhost:8080/testing/123';
},
parse : function(resp) {
console.log(resp);
// this prints:
// "[{"name":"helloworld1"},{"name":"helloworld2"}]"
this.add(resp);
this.add(new Menu({name:"black perl"}));
console.log(this);
// the length of the object in the console log is 0
}
});
window.MenuView = Backbone.View.extend({
tagName: 'li',
initialize: function() {
_.bindAll(this, 'render');
},
render: function() {
$(this.el).html('<span>'+this.model.get('name')+'</span>');
return this;
}
});
window.MenuListView = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
_.bindAll(this, 'render');
},
render: function() {
this.model.each(function(menu) {
$(this.el).append(new MenuView({model:menu}).render().el);
});
return this;
}
});
var view;
AppView = Backbone.View.extend({
el: $("body"),
initialize: function () {
this.menus = new MenuCollection();
this.menuListView = new MenuListView({model:this.menus});
view = this.menuListView;
this.menus.fetch({success: function(){console.log("success");
console.log(view.render().el);}});
},
events: {
}
});
var appview = new AppView;
})(jQuery);
回答1:
You're misunderstanding how parse works:
parse
collection.parse(response)
parse is called by Backbone whenever a collection's models are returned by the server, in fetch. The function is passed the raw
response
object, and should return the array of model attributes to be added to the collection.
So if you're getting [{"name":"helloworld1"},{"name":"helloworld2"}]
from the server, you don't even need a parse
implementation.
The strange behavior you're seeing with add
is more interesting. If we look at fetch, we see this:
fetch: function(options) {
//...
options.success = function(resp, status, xhr) {
collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
if (success) success(collection, resp);
};
//...
}
You're calling fetch
without the add
option set so things happen like this:
collection.parse
is called.- Your
parse
adds a few things and callsconsole.log
. - Your parse doesn't return anything at all.
collection.reset
is called to add whatparse
returned.reset
will clear out the collection and then adds nothing becauseparse
didn't return anything.
Some console.log
implementations put a live reference in the console, that's why you get an empty collection in the console: console.log(this)
ends up showing this
after the reset
call.
回答2:
Actually, another problem you have is that you are not passing "this" into the context of the for loop inside your view rendering. Thus, when you return the "el" element, your html page will be blank without the contents from the server.
回答3:
Bear in mind that the parse method as availble from backbone.js 0.9+ version 0.5.3 would not call parse.
来源:https://stackoverflow.com/questions/9675421/backbone-js-collection-not-adding-objects