在事件/回调驱动的JavaScript应用程序中管理“this”

时间:2012-03-21 22:21:47

标签: javascript jquery jquery-ui backbone.js

我想知道在jQuery和Backbone.js等框架中经常使用的回调中处理“this”引用的预期方法是什么

这是我遇到问题的简化示例,使用Backbone.js和jQuery UI,但它并不是特定于这些框架。

var MyView = Backbone.View.extend({
   render: function() {
      $('#mybutton').click(function() {
         // My code in here
      });
   },

   callMe: function() {
      alert('Rawr!');
   }
});

现在,我如何从点击处理程序中引用MyView实例?例如,我如何从点击处理程序中调用“callMe”?在处理程序之外我只是调用this.callMe();但是“this”会被click处理程序中的DOM元素替换。解决这个问题的最佳方式是什么?

2 个答案:

答案 0 :(得分:8)

最有效的方法是将this的结果存储在另一个变量中,然后在回调中使用它;

var MyView = Backbone.View.extend({
   render: function() {
      var that = this;

      $('#mybutton').click(function() {
          // use that for MyView and this for the DOM element
      });
   },

   callMe: function() {
      alert('Rawr!');
   }
});

或者,您可以使用jQuery.proxy()或HTML 5(beware of backwards compatabilityFunction.prototype.bind()方法来定义this的值。显然,你放弃了使用this来引用DOM元素的能力,因此必须依赖target对象的Event属性;

var MyView = Backbone.View.extend({
   render: function() {
      $('#mybutton').click((function(e) {
          // Use `this` for MyView and `e.target` for the DOM element
      }).bind(this));
   },

   callMe: function() {
      alert('Rawr!');
   }
});

或者:

var MyView = Backbone.View.extend({
   render: function() {
      $('#mybutton').click(jQuery.proxy(function(e) {
          // Use `this` for MyView and `e.target` for the DOM element
      }, this));
   },

   callMe: function() {
      alert('Rawr!');
   }
});

答案 1 :(得分:2)

我就是这样做的。 events属性是将大多数事件处理程序列在一个位置的简便方法。 _.bindAll(this)将使this引用所有MyView函数中的视图。

var MyView = Backbone.View.extend({
   events: {
     'click #mybutton': 'clickHandler'
   },
   initialize: function() {
     _.bindAll(this);
   }
   render: function() {

   },
   clickHandler: function() {
     this.callMe();
   },
   callMe: function() {
      alert('Rawr!');
   }
});