如何将'this'传递给使用骨干的事件?

时间:2012-04-21 02:01:38

标签: javascript backbone.js

我有一个将函数绑定到单击的事件。单击会在同一视图中调用另一个函数。不幸的是,范围不是正确的范围。当我尝试执行此.otherFunction()时,分配给click的函数与this.otherFunction()的范围不同。有没有办法传入otherFunction()的范围?

initialize: function() {
  this.render();

  if (joinedGoalList.get(this.model.id) != null) {
    this.renderLeaveGoal();
  } else {
    this.renderJoinGoal();
  }
},

events: {
  "keypress #goal-update": "createOnEnter",
  "click #join-goal": "joinGoal",
  "click #leave-goal": "leaveGoal",
},

joinGoal: function() {
  matches = joinedGoalList.where({id: this.model.get("id")});
  if (matches.length == 0) {
    joinedGoalList.create({goal_id: this.model.get("id")}, {wait: true, success: function() {
      var self = this;
      self.renderLeaveGoal();
    }, error: function() {
      console.log("error");
    }});
  }
},

renderLeaveGoal: function() {
  console.log("render leave goal");
  var template = _.template($("#leave-goal-template").html());
  console.log(template);
  $("#toggle-goal-join").html(template());
},

这些都属于同一观点。

编辑: 嗯,现在问题是我收到这个错误: 未捕获的TypeError:Object [object DOMWindow]没有方法'renderLeaveGoal'。这似乎是我保存了错误的范围吗?

4 个答案:

答案 0 :(得分:5)

标准技术是做类似

的事情
var self = this;

然后你可以做

self.otherFunction();

取代

this.otherFunction();

答案 1 :(得分:2)

deltanovember的回答是正确的,但他没有解释为什么这是正确的,我觉得这很重要:

Javascript中的范围很混乱。我发现跟踪它的最简单方法是在执行某些事情时考虑。如果一段代码立即执行,它可能与“this”在同一范围内运行。如果稍后要调用一个函数,它可能在一个完全不同的范围内运行,它有自己的“this”概念。

在您的示例中,您提供的匿名函数作为成功回调将在稍后运行,并且它不会限定为与定义所述回调时运行的代码相同的“this”。这就是您收到错误的原因:renderLeaveGoal是在定义回调的范围内定义的,而不是回调执行的范围。

现在,为了使这更加混乱,定义回调时定义的变量 在该回调范围内可用。这就是为什么deltanovember的答案有效。通过在定义成功回调时伪装变量中的“this”,回调仍然可以在以后运行时访问它,尽管范围完全不同。

我希望这是有道理的。评论如果没有,我会再试一次:))

答案 2 :(得分:2)

您还可以使用Underscore的bindAll功能,如下所示:

initialize: function() {
    _.bindAll(this);
}

在幕后,Underscore将使用代理版本替换对象中的所有函数调用,这些代理版本将“this”设置为与原始对象相同的“this”。当然,如果你的一个方法里面有自己的匿名回调函数,那么你需要完成整个“self = this”舞蹈; bindAll仅修复对象上“外部”方法的上下文。

我已经养成了使用_.bindAll作为我的每个View的initialize()方法的第一行的习惯。

答案 3 :(得分:1)

该函数附加到视图,因此您需要从View对象中调用它。

success: this.renderLeaveGoal

在这种情况下,您不需要匿名函数,因为视图函数会自动绑定到视图的上下文。