Почему события не срабатывают после второго рендера в Backbone.js?
Я создаю приложение в Backbone.js, у которого есть родительское и множественное дочерние представления. Представления child содержат ссылки, которые они прослушивают и выполняют функцию.
Родитель хранит список всех представлений детей. В функции рендеринга после завершения вычисления собственного html он выполняет следующие действия:
$(this.el).html(html);
for (var i = 0; i < this.views.length; i++){
$('.children', this.el).append(this.views[i].render().el);
}
ОТВЕТ: Проблема заключалась в том, что я создавал ссылку во время рендеринга. То есть на первом рендере (который был вызван из init) событие успешно привязано к ссылке. Однако, поскольку все последующие вызовы рендеринга воссоздают весь элемент, в новой ссылке не было привязанного к нему обработчика. Это было решено с помощью решения @Tom Tu добавления this.delegateEvents()
в рендеринг
Ответы
Ответ 1
Вероятно, вы используете функцию jquery remove
для удаления подсмотров из представления - она автоматически удаляет все события, связанные с элементом (this.el), - устанавливается в объекте events
. Вы можете использовать метод this.delegateEvents()
в рендеринге субвью после того, как вы визуализируете шаблон, чтобы переустановить делегаты событий, установленные в объекте events
, или использовать метод jquery detach
вместо этого, чтобы удалить элементы из DOM без удаления привязок событий (ссылка). Метод delegateEvents
довольно дорогостоящий, и поэтому я рекомендую метод detach
для удаления элементов, которые вы хотите использовать повторно, если вы выполняете длинные списки подзаголовков - не имеет значения, если это всего лишь несколько представлений.
Другая возможность заключается в том, что вы неправильно установили объект events
- трудно сказать из объема предоставленного кода, но я ставлю ставку на первый.
Ответ 2
Очень распространенная проблема. Для будущих искателей этого вопроса, здесь есть замечательная статья о рендеринге представления:
Вам просто нужно убедиться, что делегирование делегатов вызвано для повторной проверки событий в ваших подпрограммах в любое время .html(). И поскольку Backbones setElement уже вызывает делегатEvents, быстрое решение может выглядеть так...
http://ianstormtaylor.com/rendering-views-in-backbonejs-isnt-always-simple/