jQuery动画回调+ Backbone:无法调用undefined的方法'remove'

时间:2013-02-09 09:50:26

标签: javascript jquery backbone.js callback closures

我不是JavaScript的新手,但我经常发现它的灵活方式(比如定义匿名函数作为回调及其范围)非常混乱。我仍在努力的一件事是关闭和范围。

以此示例(来自Backbone模型):

'handleRemove': function() {
    var thisModel = this;
    this.view.$el.slideUp(400, function() { thisModel.view.remove(); });
},

删除/删除模型后,将为其视图设置动画,最后将其从DOM中删除。这很好 - 但最初我尝试了以下代码:

'handleRemove': function() {
    var thisModel = this;
    this.view.$el.slideUp(400, thisModel.view.remove );
},

哪个基本相同,但没有remove {)调用的function() {}包装。

有人可以解释为什么后一个代码不起作用?我得到以下异常/回溯:

Uncaught TypeError: Cannot call method 'remove' of undefined backbone-min.js:1272
_.extend.remove backbone-min.js:1272
jQuery.speed.opt.complete jquery-1.8.3.js:9154
jQuery.Callbacks.fire jquery-1.8.3.js:974
jQuery.Callbacks.self.fireWith jquery-1.8.3.js:1084
tick jquery-1.8.3.js:8653
jQuery.fx.tick

谢谢!

1 个答案:

答案 0 :(得分:3)

这是因为回调函数的上下文(this)更改为jQuery动画的元素。

var obj = { fn: function() {         // Used as below, the following will print:
                alert(this === obj); // false
                alert(this.tagName); // "DIV"
          }};
$('<div>').slideUp(400, obj.fn);

此外,Backbone的view.remove函数看起来像这样(source code):

remove: function() {
  this.$el.remove();
  this.stopListening();
  return this;
},

由于this不再是Backbone视图对象,因此未定义$el。因此,您得到“无法调用方法'删除'未定义的'错误。

避免错误的另一种方法是使用Underscore的_.bind方法:

this.view.$el.slideUp(400, _.bind(thisModel.view.remove, this) );