【问题标题】:jQuery animate callback + Backbone: Cannot call method 'remove' of undefinedjQuery动画回调+主干:无法调用未定义的方法“删除”
【发布时间】:2013-02-09 09:50:25
【问题描述】:

我不是 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

谢谢!

【问题讨论】:

    标签: javascript jquery backbone.js callback closures


    【解决方案1】:

    这是因为回调函数的上下文 (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) );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      相关资源
      最近更新 更多