Reputation: 4931
I have Person
model and I am retrieving a person info inside a view. The success
callback FetchSuccess
executes when the response has an object. But when response is empty, the callback is not called. Any Guess?
Models.Basic = Backbone.Model.extend({
parse: function(response) {
return response;
}
});
Models.PersonModel = Backbone.Model.extend({
url: function() {
return '/person/' + this.data.id;
}
});
Backbone.View.extend({
template: Templates['template'],
initialize: function(options) {
this.id = options.id;
_.bindAll(this, 'FetchSuccess');
this.personModel = new Models.PersonModel();
this.model = new Models.Basic();
this.fetchData();
return this;
},
render: function() {
this.$el.append(this.template(this.model.toJSON()));
},
fetchData: function() {
this.personModel.data = {
id: this.id
};
this.personModel.fetch({
context: this,
success: this.FetchSuccess
});
},
FetchSuccess: function() {
this.model.set({
name: this.personModel.get('name');
});
this.render();
}
});
Upvotes: 0
Views: 358
Reputation: 17430
this.personModel = new Models.PersonModel();
This is a Backbone Model, not a collection.
this.personModel.fetch({
reset: true, // this doesn't exist on model
success: this.FetchSuccess
});
You can't fetch a model without an id
. Also, the model, when fetching, expects an object to be returned.
If you want to fetch a specific person, give an id
to the model, then fetch.
this.personModel = new Models.PersonModel({ id: "id_here" });
// ...
this.personModel.fetch({
context: this,
success: this.FetchSuccess
});
Here's the code with the corrections
// parse isn't needed if you're not going to parse something
Models.Basic = Backbone.Model.extend({});
Models.PersonModel = Backbone.Model.extend({
urlRoot: 'person/', // this handles putting the id automatically
});
Backbone.View.extend({
template: Templates['template'],
initialize: function(options) {
this.id = options.id;
// pass the id here
this.personModel = new Models.PersonModel({ id: this.id });
this.model = new Models.Basic();
this.fetchData();
// makes no sense in the initialize since it's never called
// manually and never used to chain calls.
// return this;
},
render: function() {
// render should be idempotent, so emptying before appending
// is a good pattern.
this.$el.html(this.template(this.model.toJSON()));
return this; // this is where chaining could happen
},
fetchData: function() {
// This makes no sense unless you've stripped the part that uses it.
// this.personModel.data...
this.personModel.fetch({
context: this, // pass the context, avoid `_.bindAll`
success: this.onFetchSuccess,
error: this.onFetchError
});
},
onFetchSuccess: function() {
this.model.set({
name: this.personModel.get('name')
});
this.render();
},
onFetchError: function() { this.render(); }
});
You could catch the error with the error
callback, or just do nothing and render by default, and re-render on fetch.
You could also listen to the model events (inside the initialize
):
this.listenTo(this.personModel, {
'sync': this.FetchSuccess,
'error': this.onFetchError
});
this.personModel.fetch();
Upvotes: 1