Ответ 1
Обычно лучше использовать listenTo()
Из Основы основы от Адди Османи:
Пока
on()
иoff()
добавляют обратные вызовы непосредственно к наблюдаемому объекту,listenTo()
указывает объекту прослушивать события на другом объекте, позволяя слушателю отслеживать события, для которых он прослушивания.stopListening()
можно впоследствии вызвать на слушателя чтобы остановить прослушивание событий:var a = _.extend({}, Backbone.Events); var b = _.extend({}, Backbone.Events); var c = _.extend({}, Backbone.Events); // add listeners to A for events on B and C a.listenTo(b, 'anything', function(event){ console.log("anything happened"); }); a.listenTo(c, 'everything', function(event){ console.log("everything happened"); }); // trigger an event b.trigger('anything'); // logs: anything happened // stop listening a.stopListening(); // A does not receive these events b.trigger('anything'); c.trigger('everything');
Если вы используете и выключаете и удаляете представления и их соответствующие модели в то же время, как правило, проблем нет. Но проблема возникает, когда вы удаляете представление, зарегистрированное для уведомления о события на модели, но вы не удаляете модель или не вызываете удалить обработчик событий views. Поскольку модель имеет ссылку на функция обратного вызова вида, сборщик мусора JavaScript не может удалить вид из памяти. Это называется призракным видом и является формой утечки памяти, что является обычным явлением, поскольку модели обычно имеют тенденцию пережить соответствующие представления во время жизненного цикла приложений. Для подробную информацию о теме и решении, проверьте эту замечательную статью на Дерик Бэйли.
Практически каждый вызываемый объект
on
требует такжеoff
чтобы сборщик мусора выполнял свою работу.listenTo()
изменения, позволяющие представлениям привязываться к уведомлениям модели и отменить привязку из всех них одним звонком -stopListening()
.Реализация по умолчанию
View.remove()
выполняет вызовstopListening()
, гарантируя, что любые слушатели, связанные с использованиемlistenTo()
не связаны до того, как будет уничтожено представление.var view = new Backbone.View(); var b = _.extend({}, Backbone.Events); view.listenTo(b, 'all', function(){ console.log(true); }); b.trigger('anything'); // logs: true view.listenTo(b, 'all', function(){ console.log(false); }); view.remove(); // stopListening() implicitly called b.trigger('anything'); // does not log anything