При написании Angular-директивы можно использовать любую из следующих функций для управления поведением DOM, содержимым и внешним видом элемента, для которого объявлена директива:
- компиляции
- контроллер
- предварительно связь
- пост-ссылка
Кажется, есть некоторая путаница относительно того, какую функцию следует использовать. Этот вопрос охватывает:
Директивные основы
- Как объявить различные функции?
- В чем разница между исходным шаблоном и шаблоном экземпляра ?
- В каком порядке выполняются директивные функции?
- Что еще происходит между этими вызовами функций?
Природа функции, делай и не делай
Смежные вопросы:
- Директива: ссылка против компиляции против контроллера .
- Разница между функциями 'controller', 'link' и 'compile' при определении директивы angular.js .
- В чем разница между функцией компиляции и компоновки в angularjs .
- Разница между прекомпиляцией и посткомпиляцией в директивах AngularJS? ,
- Angular JS Directive - Шаблон, компиляция или ссылка? ,
- ссылка post против pre link в угловых директивах js .
angularjs
angularjs-directive
Izhaki
источник
источник
Ответы:
В каком порядке выполняются директивные функции?
Для одной директивы
Исходя из следующего плана , рассмотрим следующую HTML-разметку:
Со следующим объявлением директивы:
Вывод консоли будет:
Мы видим, что
compile
сначала выполняется, затемcontroller
, затемpre-link
и последнийpost-link
.Для вложенных директив
Оригинальная HTML-разметка часто состоит из вложенных элементов, каждый из которых имеет свою собственную директиву. Как в следующей разметке (см. Plunk ):
Вывод консоли будет выглядеть так:
Здесь можно выделить две фазы - фазу компиляции и фазу линка .
Фаза компиляции
Когда DOM загружен, Angular начинает фазу компиляции, где он проходит разметку сверху вниз и вызывает
compile
все директивы. Графически мы можем выразить это так:Возможно, важно упомянуть, что на этом этапе шаблоны, которые получает функция компиляции, являются исходными шаблонами (а не шаблоном экземпляра).
Фаза связи
Экземпляры DOM часто являются просто результатом того, что исходный шаблон отображается в DOM, но они могут быть созданы
ng-repeat
или внедрены на лету.Всякий раз, когда новый экземпляр элемента с директивой отображается в DOM, начинается фаза соединения.
На этом этапе Angular вызывает
controller
,pre-link
перебирает дочерние элементы и вызываетpost-link
все директивы, например:источник
Что еще происходит между этими вызовами функций?
Различные функции директив выполнены из двух других в пределах угловых функций , вызываемых
$compile
(где директиваcompile
выполняются) и внутренняя функцией , называемойnodeLinkFn
(где директивыcontroller
,preLink
иpostLink
исполняются). В угловой функции происходят разные вещи до и после вызова директивных функций. Возможно, наиболее заметно это рекурсия ребенка. На следующем упрощенном рисунке показаны основные этапы на этапах компиляции и компоновки:Чтобы продемонстрировать эти шаги, давайте используем следующую разметку HTML:
Со следующей директивой:
Compile
В
compile
API выглядит следующим образом:Часто параметры имеют префикс
t
для обозначения элементов и предоставленных атрибутов, которые относятся к исходному шаблону, а не к экземпляру.Перед вызовом
compile
включенный контент (если есть) удаляется, а шаблон применяется к разметке. Таким образом, элемент, предоставленныйcompile
функции, будет выглядеть так:Обратите внимание, что включенный контент не вставляется повторно в этот момент.
После вызова директивы
.compile
Angular будет проходить по всем дочерним элементам, включая те, которые могли быть только что введены директивой (например, элементы шаблона).Создание экземпляра
В нашем случае три экземпляра исходного шаблона выше будут созданы (by
ng-repeat
). Таким образом, следующая последовательность будет выполняться три раза, один раз за экземпляр.контроллер
controller
API включает в себя:При входе в фазу связи функция связи, возвращаемая через
$compile
, теперь снабжена областью действия.Во-первых, функция ссылки создает дочернюю область (
scope: true
) или изолированную область (scope: {...}
) по запросу.Затем выполняется контроллер, снабженный областью действия элемента экземпляра.
Pre-ссылка
В
pre-link
API выглядит следующим образом:Практически ничего не происходит между вызовом директивы
.controller
и.preLink
функции. Angular по-прежнему дают рекомендации относительно того, как каждый из них должен использоваться.После
.preLink
вызова функция link будет проходить через каждый дочерний элемент - вызывая правильную функцию link и присоединяя к ней текущую область (которая служит родительской областью для дочерних элементов).Пост-ссылка
post-link
API аналогичен изpre-link
функции:Возможно, стоит заметить, что после вызова
.postLink
функции директивы процесс связывания всех ее дочерних элементов завершен, включая все дочерние.postLink
функции.Это значит, что к тому времени, когда
.postLink
звонят, дети «вживую» готовы. Это включает в себя:Шаблон на этом этапе будет выглядеть так:
источник
Как объявить различные функции?
Компиляция, Контроллер, Пре-ссылка и Пост-ссылка
Если нужно использовать все четыре функции, директива будет выглядеть следующим образом:
Обратите внимание, что compile возвращает объект, содержащий функции pre-link и post-link; в угловом жаргоне мы говорим, что функция компиляции возвращает функцию шаблона .
Компиляция, контроллер и пост-ссылка
Если в
pre-link
этом нет необходимости, функция компиляции может просто вернуть функцию post-link вместо объекта определения, например, так:Иногда желательно добавить
compile
метод после определения (post)link
метода. Для этого можно использовать:Контроллер и пост-ссылка
Если функция компиляции не требуется, можно полностью пропустить ее объявление и предоставить функцию post-link под
link
свойством объекта конфигурации директивы:Нет контроллера
В любом из приведенных выше примеров можно просто удалить
controller
функцию, если она не нужна. Так, например, еслиpost-link
нужна только функция, можно использовать:источник
В чем разница между исходным шаблоном и шаблоном экземпляра ?
Тот факт, что Angular допускает манипулирование DOM, означает, что входная разметка в процессе компиляции иногда отличается от выходной. В частности, некоторая входная разметка может быть клонирована несколько раз (например, с помощью
ng-repeat
) перед передачей в DOM.Угловая терминология немного противоречива, но все же различает два типа разметки:
Следующая разметка демонстрирует это:
HTML-код источника определяет
который служит исходным шаблоном.
Но поскольку он заключен в
ng-repeat
директиву, этот исходный шаблон будет клонирован (3 раза в нашем случае). Эти клоны являются шаблоном экземпляра, каждый появится в DOM и будет связан с соответствующей областью действия.источник
Функция компиляции
compile
Функция каждой директивы вызывается только один раз, когда Angular загружается.Официально это место для выполнения (исходных) шаблонных манипуляций, которые не связаны с областью действия или привязкой данных.
В первую очередь это делается в целях оптимизации; рассмотрим следующую разметку:
<my-raw>
Директива будет оказывать определенный набор DOM разметки. Таким образом, мы можем либо:ng-repeat
дублирование исходного шаблона (<my-raw>
), а затем изменить разметку каждого шаблона экземпляра (внеcompile
функции).compile
функции), а затем разрешитеng-repeat
дублировать его.Если в
raws
коллекции 1000 предметов , последний вариант может быть быстрее предыдущего.Делать:
Не делайте
источник
Функция контроллера
controller
Функция каждой директивы вызывается всякий раз, когда создается новый связанный элемент.Официально,
controller
функция где один:Опять же, важно помнить, что если директива включает в себя изолированную область, все свойства внутри нее, которые наследуются от родительской области, еще не доступны.
Делать:
Не делайте:
источник
Функция пост-ссылки
Когда
post-link
вызывается функция, выполняются все предыдущие шаги - привязка, включение и т. Д.Обычно это место для дальнейших манипуляций с отображаемым DOM.
Делать:
источник
Функция предварительной ссылки
pre-link
Функция каждой директивы вызывается всякий раз, когда создается новый связанный элемент.Как показано ранее в разделе порядка компиляции,
pre-link
функции называются parent-then-child, тогда какpost-link
функции называютсяchild-then-parent
.pre-link
Функция используется редко, но может быть полезен в специальных ситуациях; например, когда дочерний контроллер регистрирует себя с родительским контроллером, но регистрация должна быть вparent-then-child
моде (ngModelController
делает вещи таким образом).Не делайте:
источник