Изменение DOM-дерева
Перестаньте изменять DOM-дерево в контроллере, с помощью JQuery. Серьезно. Это относится к добавлению, удалению элементов, получению их содержимого, скрытие и показывание элементов. Для этого используйте встроенные директивы или пишите свои, когда это необходимо.
Если есть проблемы с избавлением от этой привычки - попробуйте удалить JQuery из проекта. Серьезно. У Angular есть свой сервис $hppt и другие директивы, которые заменяют JQuery. Angular поставляется со своим JQLite, его возможности используются при написании директив, особенно привязка к событиям.
Попытка дублировать функционал, который уже существует
Есть большая верятность, что не только вашему приложению понадобился данный функционал. Есть некоторый функционал, который постоянно пытаются реализовать по своему.
ng-repeat, частенько дублируется. Программисты пытаются добавить элементы, полученные от сервера, используя JQuery. Это плохо. Именно для этого создан ng-repeat. И он справляется с этим отлично. Сохраниете данные в массив в своем $scope и выведите в DOM с помощью ng-repeat.
ng-show, тоже часто дублируют. Показ и скрытие элементов по условиню используя JQuery, частый паттерн для других приложений, но у Angular есть решение лучше. ng-hide или ng-show, скрытие или показ элемента по условию, основываясь на булиеновском заначении. Пример:
<div ng-show="!loggedIn"><a href="#/login">Click here to log in</a></div>
Обратите внимание на похожий ng-disabled. Так же на мощный ng-switch, он должен быть использован вместо повторяющихся ng-shows.
ng-class - последний из большой тройки. Применение класса для элемента, в ручную используя JQuery, основываясь на условии. Конечно в Angular есть способ лучше. Можно передать в ng-class список именн классов, разделенных проблемлом и их условий, вот пример:
в ng-class передается объект, в котором перечислены CSS имена классов и условия их применения. Будут использоваться только те кслассы, условие для которых получилось true.ng-class - последний из большой тройки. Применение класса для элемента, в ручную используя JQuery, основываясь на условии. Конечно в Angular есть способ лучше. Можно передать в ng-class список именн классов, разделенных проблемлом и их условий, вот пример:
<div ng-class="{ errorClass: isError, warningClass: isWarning, okClass: !isError && !isWarning }">...</div>
$watch и $apply
Двунаправленное связывание данных - это основа Angular. Тем неменее это не магия и в некоторых ситуациях тебе необходимо подсказать фреймворку правильное направление.
Когда ты связываешь значение с элемнтом используя ng-mode, ng-repeat и другие Angular создает $watch над этим значением. Далее, когда значение в области видимости изменится, все $watch'ы, наблюдающие за данным элементом, выполнятся, и обновится все остальное.
Иногда, чаще всего, когда ты создаешь свои директивы, необходимо объявить собственные $watch, над переменными в области видимости, позволяющие директиве реагировать на изменения.
С другой стороны, когда ты изменяешь значение в области видимости, но приложение не реагирует. Angular проверяет изменение переменных в области видимости после того, как код отработал, например когда срабатывает ng-click, то Angular проверит изменения и отреагирует. Тем не менее, код вне Angular, должен самостоятельно вызвать метод scope.$apply(), чтоб произвести обновление. Обычно это требуется в обработчиках событий в кастомных директивах.
Использование ng-repeat с другими директивами
ng-repeat - наиболее полезная и одна из самых мощных директив в Angular. Однако преобразование DOM является трудоемким процессом. Поэтому применение других директив (ng-show, ng-hide, ng-controlle и др) к тому же элементу, что и ng-repeat может привести к проблемам. Если необходимо применить директиву ко всему объекту ng-repeat, оберните его в родительский элемент и примените директиву к нему. Если необходимо применить директиву к каждому элементу - примените директиву к элементу с ng-repeat.
$rootScope существует, но может создать проблемы
Области видимости в Angular формируются иерархично, наследуясь от основной области видимости верхушки дерева. Обычно, это можно игнорировать, т.к. у каждого вью имеют контроллеры, у которых есть своя область видимости.
Изредка, есть данные, которые необходимо сделать глобальными для всего приложения. Для этого можно проинжектить $rootScope и установить в значение в нем, как в других областях видимости. Поскольку области наследуются от корневой области, эти значения будут доступны директивам, таким как ng-show так же как значения в локальной $scope.
Конечно, использовать глобальное состояние плохо, а потому стоит использовать $rootScope с умом, как вы бы (надеюсь) обращались с глобальными переменными в любом другом языке. В частности, не используйте их для кода, только в данных. Если будет желание вставить функцию на $rootScope, то почти всегда лучше поместить его в сервис, который может быть инжектирован где это необходимо, и легко протестирован. С другой стороны, не создавайте сервис, чья единственная цель хранение и возврат бита данных.
PS мой перевод данной статьи
Комментариев нет :
Отправить комментарий