Backbone.js listenTo窗口调整大小throw [object Object]没有方法'apply'错误

时间:2013-01-22 14:28:40

标签: backbone.js backbone-events

问题:

我正在尝试使用Backbone.js中的新listenTo()方法从视图中将resize事件附加到窗口。该事件似乎绑定到窗口,但是,当窗口实际被重置时,将引发以下错误:

  

未捕获TypeError:对象[object Object]没有方法'apply'   jquery.js:2 p.event.dispatch   jquery.js:2 p.event.add.g.handle.h

以下是将事件附加到视图的代码:

this.listenTo($(window),"resize", this.resizeContext, this));

这是resizeContext函数:

  resizeContext: function(event) {

            console.log("resizing context for "+this.id);

            this.setHeight();

            // trigger resize event (use event bus)
            this.options.vent.trigger("resize", event);

        }

注意:使用标准$(window).on("resize",this.resizeContext)附加事件并按预期运行。我正在尝试利用添加到stopListening()

的新view.remove();功能

3 个答案:

答案 0 :(得分:33)

新的listenTostopListeningBackbone.Events mixin的方法,它们只能用于侦听由.trigger触发的Backbone事件,例如内置的collection:addmodel:change事件。

这意味着您无法将stopListening功能用于window:resize等DOM事件。

请考虑改为覆盖View.remove方法。

var SomeView = Backbone.View.extend({
  initialize:function() {
    $(window).on("resize",this.resizeContext)
  },

  remove: function() {
    $(window).off("resize",this.resizeContext);
    //call the superclass remove method
    Backbone.View.prototype.remove.apply(this, arguments);
  }
});

答案 1 :(得分:10)

如果您想继续使用listenTo,您可能需要使用以下一个关闭DOM元素的包装器:

/**
 * Use Backbone Events listenTo/stopListening with any DOM element
 *
 * @param {DOM Element}
 * @return {Backbone Events style object}
 **/
function asEvents(el) {
    var args;
    return {
        on: function(event, handler) {
            if (args) throw new Error("this is one off wrapper");
            el.addEventListener(event, handler, false);
            args = [event, handler];
        },
        off: function() {
            el.removeEventListener.apply(el, args);
        }

    };
}

示例:

view.listenTo(asEvents(window), "resize", handler);

,将在view.remove()view.stoplistening()

上自动删除收听者

这是多个事件监听器https://gist.github.com/epeli/5927950

的更复杂的实现

答案 2 :(得分:1)

在我的代码中,我需要这样做      .debounce((this.resizeContext).bind(本))。

这使得关闭变得更加困难。作为一个肮脏的解决方案,我只是在删除视图时关闭所有'resize'监听器。 我想在新视图中,如果有任何调整大小的侦听器,它将再次打开。

remove: function() {
    $(window).off("resize");
    //call the superclass remove method
    Backbone.View.prototype.remove.apply(this, arguments);
}