Делегирование событий в AngularJS. Попытка разобраться

от автора

Евгений Гришковец, спектакль 'Как я съел собаку'Гришковец как бы говорит нам «А давайте разберемся»

В комментариях к статье мною был задан вопрос о делегировании в AngularJS в контексте того, что привычный многим императивный способ назначения обработчика для группы элементов аля

$('ul').on('click', 'li', function(){ // обработчик .... 

не совсем приемлем в декларативном AngularJS. Собственно, последовал совет использовать свою директиву, решающую проблему делегирования. На самом деле, на ум мне ничего толкового не пришло, и я решил погуглить, наткнулся на такой вариант: создаем директиву, которую необходимо установить на родительский для группы нужных нам элементов узел, который регистрирует слушателя.
Вот демо.

А вот 2 интересующие нас части кода:

html <ul bn-delegate="li a | selectFriend( friend )">           <li ng-repeat="friend in friends">               <!-- Delegate target. -->             <a href="#">{{ friend.name }}</a>             <!-- Delegate target. -->           </li>       </ul> 
//js                     element.on(                         "click.bnDelegate",                         selector,                         function( event ) {                               // Prevent the default behavior - this is                             // not a "real" link.                             event.preventDefault();                               // Find the scope most local to the target                             // of the click event.                             var localScope = $( event.target ).scope();                               // Invoke the expression in the local scope                             // context to make sure we adhere to the                             // proper scope chain prototypal inheritance.                             localScope.$apply(                                 function() {                                       expressionHandler( localScope );                                   }                             );                           }                     ); 

Но подождите. В зависимостях получается jQuery (можно обойтись без него, но тем не менее), но это пол беды. В дебрях директивы все тот же императивный подход. Собственно, в этот момент я решил опубликовать пост, с попыткой разобраться в подходах к делегированию в Angular, в комментарии призываются все, кому есть что сказать по этому поводу.

В попытке прояснить ситуацию наткнулся на вот такое issue. На просьбу пользователя запилить возможность автоматического привязывания события к родительскому элементу, при использовании ng-repeat, с мотивацией более лучшей производительности был отправлен за анализом производительности.

image

В итоге этот товарищ сказал, что сделал «простые» тесты, убедился что был не прав скрипач не нужен. Тема закрыта, печаль.

Если взвесить за и против делегирования, то получается
Плюсы:

  • Упрощает инициализацию и экономит память: не нужно вешать много обработчиков.
  • Меньше кода: при добавлении и удалении элементов не нужно ставить или снимать обработчики.
  • Удобство изменений: можно массово добавлять или удалять элементы путём изменения innerHTML.

Минусы:

  • Во-первых, событие должно всплывать. Большинство событий всплывают, но не все.
  • Во-вторых, делегирование создает дополнительную нагрузку на браузер, ведь обработчик запускается, когда событие происходит в любом месте контейнера, не обязательно на элементах, которые нам интересны.
    Но обычно эта нагрузка невелика и не является проблемой.

На самом деле сколько-нибудь приближенных к реальности тестов я придумать не смог, на элементарных примерах разницы не видно абсолютно. Поэтому призываю в комментариях обсудить, так ли необходимо юзать делегирование?

ссылка на оригинал статьи http://habrahabr.ru/post/218813/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *