鉴于下面的骨干视图功能,将this
(即当前视图)传递给回调中定义的匿名函数的正确方法是什么?
addSomething: function(e) {
var newSomething= this.model.somethings.create({
someProperty: xxx
}, {
success: function(m, response) {
this.doSomething(); //***HERE****
},
error: function(m, response) {
//Error
}
});
},
如果没有和更改,anon函数中的this
将设置为窗口。
我可以像这样设置一个引用:
var thisView = this;
然后在anon函数中引用thisView
而不是this
,但这看起来并不优雅。还有更好的方法吗?
答案 0 :(得分:28)
为了更好地组织我的代码并解决这个问题,我从不直接将我的调用成功和错误回调放在一起。我总是把它们分成自己的功能。这让我保持代码干净,并使用_.bindAll
方法确保我有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
}
});
答案 1 :(得分:2)
答案 2 :(得分:2)
您还可以使用that
约定:
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
}
});
}
这在javascript中是一种非常常见的模式,尤其是在使用嵌套函数丢失上下文时。嵌套函数可以访问外部函数中的变量,因此可以正常工作。
Derick的方法使代码更清晰,无论具有额外功能的事实如何,但如果您不希望它们使用'那';)
答案 3 :(得分:1)
看到一个太多的人后感到厌倦了=这个;'我已经开始通过一个视图'属于呼叫的选项。
this.model.destroy({success:
function (model, resp, options) {
model.releaseLock(false);
window.location.href = options.view.getURLForModelID(model.get('id'));
},
error: function (model, resp, options) {
options.view.displayError(resp.message);
},
view: this
});
<强> 修改 强>
我已经习惯使用的另一个选项是使用_.bind()传递当前上下文。
this.model.destroy({success:
function (model, resp, options) {
model.releaseLock(false);
window.location.href = options.view.getURLForModelID(model.get('id'));
},
error: _.bind(function (model, resp, options) {
this.displayError(resp.message);
}, this),
});
答案 4 :(得分:0)
通过创建匿名函数,传递call
,然后立即调用,您可以在不使用bind
,apply
或this
(或Lo-Dash)的情况下看似传递上下文对象原型上的处理程序方法,如以下CoffeeScript示例所示:
View = require('views/base/view')
module.exports = class LoginPageView extends View
template: require('./templates/login-page')
events:
'submit form': '_doLogin'
# Called when the template is bound using Chaplin
attach: ->
super
@$loginButton = @$('[name="login"]')
_doLogin: (evt) ->
evt.preventDefault()
@$loginButton.attr 'disabled', true
email = @$('[name="email"]').val()
password = @$('[name="password"]').val()
@model.save {email, password},
success: (model, response, options) =>
@_loginSuccess model, response, options
error: (model, response, options) =>
@_loginError model, response, options
_loginSuccess: (model, response, options) ->
# TODO: Implement method body
_loginError: (model, response, options) ->
# TODO: Implement method body
对于参数名称可能有点冗长,而匿名函数创建的额外闭包并不是性能最佳的实现,但在与不同技能水平的人员合作时,它肯定更容易掌握和管理
答案 5 :(得分:0)
您也可以使用$.proxy:
success: $.proxy(function(m, response) {
this.doSomething();
}, this),
error: function(m, response) {
//Error
}
&#13;