Consider we are working with an API that exposes two objects, Parent and Child, where a Parent has many Child objects. The server represents this relationship in representations of Parent objects as a list of IDs of Child objects:
{
...
children: [1, 2, 5, 19, ...],
...
}
Assuming we can't change the server's response, how can we fetch Child objects when fetching Parents object using Backbone.js? Roughly, the following code is what I want, but it does not work because child.fetch() is asynchronous:
var Child = Backbone.Model.extend({
url: function() {
return "/children/" + this.model.get('id');
}
});
var Parent = Backbone.Model.extend({
parse: function(response) {
response.children = _.map(response.children, function(id) {
var child = Child({id: id});
child.fetch(); // Ideally, this would be synchronous
return child.attributes;
});
return response;
},
url: function() {
return "/parents/" + this.model.get('id');
}
});
var parent = new Parent({id: 0});
Parent.fetch();
Without this piece, I cannot render my views, which has Child views nested within Parent views:
var ParentView = Backbone.View.extend({
initialize: function() {
this.childViews = _.map(this.model.get('children'), function(child) {
return ChildView({model: child});
});
},
template: _.template($('#parent-template').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
_.each(this.childViews, function(view) {
this.$el.append(view.render().el);
});
return this;
}
});
var ChildView = Backbone.View.extend({
template: _.template($('#parent-template').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
Several solutions have occurred to me so far, but none of them work without drawbacks:
Move the
fetch()logic intoinitialize(), but this runs into all the same problems, plus leaving the model in an inconsistent state betweenfetch()andinitialize().fetch()(andrender()) the Child objects inParent.render(), but this contaminates rendering with initialization logic.
Aucun commentaire:
Enregistrer un commentaire