Backbone.js listenTo для изменения размера окна [object Object] не имеет метода 'apply' error
Проблема:
Я пытаюсь прикрепить событие изменения размера к окну из представления, используя новый метод listenTo() в Backbone.js. Событие, похоже, привязывается к окну, однако, когда окно действительно вставлено, возникает следующая ошибка:
Uncaught TypeError: Object [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();
Ответы
Ответ 1
Новые listenTo
и stopListening
являются методами микширования Backbone.Events
, и их можно использовать только для прослушивания базовых событий, которые запускаются с помощью .trigger
, таких как встроенный collection:add
, или model:change
.
Это означает, что вы не сможете использовать функциональность stopListening
для событий DOM, таких как 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);
}
});
Ответ 2
Если вы хотите использовать 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
Ответ 3
В моем коде мне нужно сделать .debounce((this.resizeContext).bind(это)).
Из-за этого сложнее отключить. Как грязное решение, я просто отключу прослушиватель "resize" при удалении представления.
Я предполагаю, что в новом представлении, если есть любой прослушиватель изменения размера, он будет снова включен.
remove: function() {
$(window).off("resize");
//call the superclass remove method
Backbone.View.prototype.remove.apply(this, arguments);
}