問題:
Backbone.jsの新しいlistenTo()メソッドを使用して、ビューからウィンドウにサイズ変更イベントをアタッチしようとしています。イベントはウィンドウにバインドされているように見えますが、ウィンドウが実際に再利用されると、次のエラーがスローされます。
Uncaught TypeError:Object [objectObject]にはメソッドがありません '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();
機能を利用しようとしています。
新しいlistenTo
とstopListening
はBackbone.Events
ミックスインのメソッドであり、.trigger
でトリガーされるバックボーンイベントをリッスンするためにのみ使用できます。組み込みのcollection:add
、またはmodel:change
イベント。
つまり、window:resize
などのDOMイベントにstopListening
機能を利用することはできません。
代わりに、View.remove
methodをオーバーライドすることを検討してください。
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);
}
});
listenTo
を使い続けたい場合は、DOM要素に次の1回限りのラッパーを使用することをお勧めします。
_/**
* 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/592795
私のコードでは、。debounce((this.resizeContext).bind(this))を実行する必要があります。
これにより、オフにするのが難しくなります。汚い解決策として、ビューを削除するときにすべての「サイズ変更」リスナーをオフにするだけです。新しいビューでは、サイズ変更リスナーがある場合は、再びオンになると思います。
remove: function() {
$(window).off("resize");
//call the superclass remove method
Backbone.View.prototype.remove.apply(this, arguments);
}