20

问题:

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

Uncaught TypeError: Object [object Object] has no method '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();

4

3 回答 3

33

新的listenToandstopListeningBackbone.Eventsmixin 的方法,它们只能用于监听由 触发的 Backbone 事件.trigger,例如内置的collection:add, 或model:change事件。

这意味着您将无法使用stopListeningDOM 事件的功能,例如window:resize.

请考虑改写该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);
  }
});
于 2013-01-22T14:47:52.557 回答
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

于 2013-07-04T14:06:21.407 回答
1

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

Which makes it harder to be turned off. As a dirty solution, I just turn off all 'resize' listener when remove the view. I guess in the new view, if there is any resize listener, it will be turned on again.

remove: function() {
    $(window).off("resize");
    //call the superclass remove method
    Backbone.View.prototype.remove.apply(this, arguments);
}
于 2014-05-15T01:01:47.063 回答