Магистраль js.listenTo против .on

В чем преимущества и недостатки следующих двух строк кода? Я не понимаю, почему есть два разных способа сделать то же самое.

this.listenTo(app.Todos, 'change:completed', this.filterOne);
app.Todos.on('change:completed', this.filterOne);

Также при использовании .on, как я могу определить контекст по умолчанию?

Ответ 1

listenTo - это более новый и лучший вариант, поскольку эти прослушиватели будут автоматически удалены для вас во время stopListening, который вызывается при удалении представления (через remove()). До listenTo существовала действительно коварная проблема с просмотрами phantom, которые висели навсегда (утечка памяти и возникновение неправильного поведения), поскольку методы просмотра ссылались на прослушиватели событий на моделях, даже если сами экземпляры представлений были давно утеряны и больше не были в DOM.

Если вы хотите прочитать предысторию для listenTo, найдите репозиторий github магистрали для listenTo и прочитайте некоторые более длительные обсуждения.

Что касается контекста по умолчанию, некоторые вещи могут быть связаны с this:

  • если вы выполняете привязку через this.listenTo, это всегда будет экземпляр представления (указанный в комментариях Вимом Лирсом)
  • без this.listenTo, история усложняется
    • Для разных событий это будет глобальный объект (лучше всего этого избежать)
    • для событий DOM, это будет исходный элемент, как в случае обычного связывания событий DOM
    • Если вы предоставляете явный контекст (третий аргумент foo.on), эталон будет использовать его (таким образом, это более надежный подход).
    • Если вы используете стандарт ECMA function () {//your event handler}.bind(this), вы также можете вручную управлять контекстом (также рекомендуется)
    • Как указывал @mu, _.bind или $.proxy доступны альтернативы ECMA function.bind
    • Для представлений с базой данных выполнение this.bindAll('onClick', ...) гарантирует, что экземпляр представления является контекстом this, когда любые методы просмотра используются как обработчики событий
  • любые события, связанные с использованием стандартного свойства представления events, будут автоматически привязаны для вас к экземпляру представления по магистрали (это пояс и подтяжки с bindAll)

Итак, чтобы обобщить некоторые рекомендации:

  • используйте свойство events, когда это возможно, поскольку оно кратким и правильным.
  • используйте this.listenTo для всех привязок к моделям и коллекциям.
  • любые дополнительные привязки не забудьте привязать контекст с помощью вашего предпочтительного метода. Обычно я использую ECMA function.bind, потому что эй, стандарты, но здесь есть несколько хороших вариантов.

Ответ 2

С listenTo объект, события которого вы хотите прослушать, передается в качестве первого аргумента. В случае on это фактически метод для этого объекта.

Преимущества listenTo over on:

  • Слушатель отслеживает все обработчики событий, что упрощает их удаление сразу при необходимости.

  • Контекст обратных вызовов всегда устанавливается на сам слушатель.