Backbone:在成功/错误回调中将正确的'this'引用传递给anon函数的正确方法

时间:2011-09-29 14:38:38

标签: javascript backbone.js

鉴于下面的骨干视图功能,将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,但这看起来并不优雅。还有更好的方法吗?

6 个答案:

答案 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)

您可以使用call

this.doSomething.call(this);

或者将您想要的任何内容this发送到doSomething

答案 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,然后立即调用,您可以在不使用bindapplythis(或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

&#13;
&#13;
        success: $.proxy(function(m, response) {
            this.doSomething(); 
        }, this),
        error: function(m, response) {
            //Error
        }
&#13;
&#13;
&#13;

相关问题