Backbone.js :在成功/错误回调中将“this”引用传递给anon函数的正确方式

jdg4fx2g  于 2022-11-10  发布在  其他
关注(0)|答案(6)|浏览(189)

给定下面的 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,但这看起来并不优雅,有更好的方法吗?

mklgxw1f

mklgxw1f1#

为了更好地组织我的代码并解决这个问题,我从来没有把成功和错误回调直接放在我的调用中。我总是把它们分成各自的函数。这样我就可以保持代码的简洁,同时也可以使用_.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
  }
});
mwkjh3gx

mwkjh3gx2#

您可以使用call

this.doSomething.call(this);

或者发送任何你想要的thisdoSomething

2exbekwf

2exbekwf3#

您也可以使用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的方法使代码更干净,不管是否有额外的函数,但如果你不想让它们使用“that”;)

watbbzwu

watbbzwu4#

Backbone有一个内置的方法来处理这个问题:“context”属性。

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
});
o2g1uqev

o2g1uqev5#

通过创建一个匿名函数,传递this,然后立即调用对象原型上的处理程序方法,可以在表面上传递上下文,而无需使用callbindapply(或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

也许它的参数名称有点冗长,并且匿名函数创建的额外闭包在性能方面不是最好的实现,但是当与不同技能水平的人一起工作时,它肯定更容易掌握和管理。

zf9nrax1

zf9nrax16#

您也可以使用$.proxy

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

相关问题