Given the backbone view function below, what is the correct way of passing this
(i.e. the current view) to the anonymous function defined in the callbacks?
addSomething: function(e) {
var newSomething= this.model.somethings.create({
someProperty: xxx
}, {
success: function(m, response) {
this.doSomething(); //***HERE****
},
error: function(m, response) {
//Error
}
});
},
Without and changes, the this
in the anon function is set to the window.
I can a set a reference like this:
var thisView = this;
and then just refer to thisView
instead of this
in the anon function, but this doesn't seem very elegant. Is there a better way?
In order to better organize my code and work around this problem, I never put success and error callbacks directly in-line with my calls. I always split them out to their own functions. This let's me keep the code clean and also use the _.bindAll
method to ensure I have the correct context for this
.
SomeView = Backbone.View.extend({
initialize: function(){
_.bindAll(this, "createSuccess", "createError");
},
addSomething: function(e) {
var newSomething= this.model.somethings.create({someProperty: xxx}, {
success: this.createSuccess,
error: this.createError
});
},
createSuccess: function(m, response) {
this.doSomething();
},
createError: function(m, response) {
//Error
}
});
You can use call:
this.doSomething.call(this);
Or send whatever you want this
to be in doSomething
You could also use the that
convention:
addSomething: function(e) {
var that = this;
var newSomething= this.model.somethings.create({
someProperty: xxx
}, {
success: function(m, response) {
that.doSomething(); //***THAT HERE****
},
error: function(m, response) {
//Error
}
});
}
This is quite a common pattern in javascript especially when context is lost with nested functions. Nested functions do have access to the variables in the outer function and hence it works.
Derick's approach makes the code cleaner, irrespective of the fact of having extra functions but if you don't want them use 'that' ;)
Backbone has a builtin way to handle this: the 'context' attribute.
this.model.destroy({
success: function (model, resp, options) {
model.releaseLock();
window.location.href = this.getURLForModelID(model.get('id'));
},
error: function (model, resp, options) {
this.displayError(resp.message);
},
context: this
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With