Может кто-нибудь объяснить простыми словами?
Документы кажутся немного тупыми. Я не понимаю суть и общую картину того, когда использовать один над другим. Пример, противопоставляющий два, был бы удивительным.
javascript
angularjs
Numan Salati
источник
источник
Ответы:
функция компиляции - используется для манипулирования DOM шаблона (т. е. манипуляции с элементом tElement = template), следовательно, манипуляции, которые применяются ко всем клонам DOM шаблона, связанным с директивой.
Функция link - используется для регистрации слушателей DOM (т. е. выражений $ watch в области видимости экземпляра), а также для манипулирования экземпляром DOM (т. е. манипулирования iElement = индивидуальный элемент экземпляра)
Это выполняется после того, как шаблон был клонирован. Например, внутри <li ng-repeat ...> функция ссылки выполняется после того, как шаблон <li> (tElement) был клонирован (в iElement) для этого конкретного элемента <li>.
$ Watch () позволяет директиве получать уведомления об изменениях свойства области экземпляра (область действия экземпляра связана с каждым экземпляром), что позволяет директиве отображать обновленное значение экземпляра в DOM - путем копирования содержимого из области действия экземпляра в ДОМ.
Обратите внимание, что преобразования DOM могут быть выполнены в функции компиляции и / или функции ссылки.
Большинству директив нужна только функция связи, так как большинство директив имеют дело только с конкретным экземпляром элемента DOM (и его областью действия).
Один из способов помочь определить, какой использовать: учтите, что функция компиляции не получает
scope
аргумента. (Я намеренно игнорирую аргумент функции связывания transclude, который получает трансклюзивную область видимости - это редко используется.) Таким образом, функция компиляции не может делать ничего, что вы хотели бы сделать, требующей (экземпляра) области действия - вы можете не наблюдайте за какими-либо свойствами области действия модели / экземпляра, вы не можете манипулировать DOM, используя информацию о области действия экземпляра, вы не можете вызывать функции, определенные в области действия экземпляра, и т. д.Однако функция компиляции (например, функция ссылки) имеет доступ к атрибутам. Поэтому, если ваши манипуляции с DOM не требуют области видимости экземпляра, вы можете использовать функцию компиляции. Вот пример директивы, которая использует только функцию компиляции, по этим причинам. Он проверяет атрибуты, но ему не нужна область видимости для выполнения своей работы.
Вот пример директивы, которая также использует только функцию компиляции. Директива нуждается только в преобразовании шаблона DOM, поэтому можно использовать функцию компиляции.
Другой способ помочь определить, какой из них использовать: если вы не используете параметр "element" в функции link, то вам, вероятно, не нужна функция link.
Поскольку большинство директив имеют функцию ссылки, я не буду приводить примеры - их должно быть очень легко найти.
Обратите внимание, что если вам нужна функция компиляции и функция ссылки (или функции предварительной и последующей ссылки), функция компиляции должна возвращать функцию (и) ссылки, поскольку атрибут 'link' игнорируется, если определен атрибут 'compile'.
Смотрите также
источник
if you don't use the "element" parameter in the link function, then you probably don't need a link function.
что вы имеете в виду «сфера» вместо «элемент»?Я несколько дней бью головой об стену, и чувствую, что нужно немного больше объяснений.
В основном, в документах упоминается, что разделение в значительной степени повышает производительность. Я хотел бы повторить, что фаза компиляции в основном используется, когда вам нужно изменить DOM ДО того, как сами подэлементы скомпилированы.
Для наших целей я собираюсь подчеркнуть терминологию, которая в противном случае сбивает с толку:
Компилятор SERVICE ($ compile) - это угловой механизм, который обрабатывает DOM и запускает различные биты кода в директивах.
ФУНКЦИЯ компиляции - это один бит кода в директиве, который запускается в определенное время с помощью SERVICE компилятора ($ compile).
Некоторые заметки о функции компиляции:
Вы не можете изменить элемент ROOT (тот, на который влияет ваша директива), поскольку он уже компилируется с внешнего уровня DOM (СЕРВИС компиляции уже сканировал директивы для этого элемента).
Если вы хотите добавить другие директивы к (вложенным) элементам, вы либо:
Нужно добавить их на этапе компиляции.
Необходимо ввести сервис компиляции в фазу компоновки и скомпилировать элементы вручную. НО, остерегайтесь что-то компилировать дважды!
Также полезно посмотреть, как работают вложенные и явные вызовы $ compile, поэтому я создал площадку для просмотра этого на http://jsbin.com/imUPAMoV/1/edit . По сути, он просто записывает шаги в console.log.
Я изложу результаты того, что вы увидите здесь. Для DOM пользовательских директив tp и sp вложены следующим образом:
Угловая компиляция SERVICE будет вызывать:
Код jsbin также имеет функцию tp post-link FUNCTION, явно вызывающую СЕРВИС компиляции по третьей директиве (вверх), которая выполняет все три шага в конце.
Теперь я хочу пройтись по паре сценариев, чтобы показать, как можно использовать компиляцию и ссылку для различных действий:
СЦЕНАРИЙ 1: Директива как МАКРО
Вы хотите динамически добавить директиву (скажем, ng-show) к чему-то в вашем шаблоне, которое вы можете получить из атрибута.
Скажем, у вас есть templateUrl, который указывает на:
и вы хотите пользовательскую директиву:
что превращает DOM в это:
По сути, вы хотите уменьшить шаблон, имея некоторую непротиворечивую структуру модели, которую ваша интерпретация может интерпретировать. Другими словами: вы хотите макрос.
Это отличное использование для фазы компиляции, поскольку вы можете основывать все манипуляции с DOM на вещах, которые вы знаете только по атрибутам. Просто используйте jQuery для добавления атрибутов:
Последовательность операций будет (вы можете увидеть это через jsbin, упомянутый ранее):
В приведенном выше примере связывание не требуется, поскольку вся работа директивы была выполнена в функции FUNCTION компиляции.
В любой момент код в директиве может попросить компилятор SERVICE запустить на дополнительных элементах.
Это означает, что мы можем сделать то же самое в функции ссылки, если вы добавите сервис компиляции:
Если вы уверены, что элементы, которые вы передаете в $ compile SERVICE, изначально не содержали директив (например, они пришли из шаблона, который вы определили, или вы просто создали их с помощью angular.element ()), то конечный результат в значительной степени так же, как и раньше (хотя вы можете повторять какую-то работу). Однако, если у элемента были другие директивы, вы просто вызывали их повторную обработку, что может вызывать все виды ошибочного поведения (например, двойная регистрация событий и наблюдений).
Таким образом, фаза компиляции - намного лучший выбор для работы в стиле макросов.
СЦЕНАРИЙ 2: конфигурация DOM через данные области
Это следует из примера выше. Предположим, вам нужен доступ к области при манипулировании DOM. Что ж, в этом случае раздел компиляции для вас бесполезен, так как это происходит до того, как область становится доступной.
Итак, допустим, вы хотите исключить входные данные с помощью валидаций, но вы хотите экспортировать свои валидации из класса ORM на стороне сервера (DRY), чтобы они автоматически применялись и генерировали надлежащий пользовательский интерфейс на стороне клиента для этих валидаций.
Ваша модель может нажать:
и вы можете захотеть директивы:
для автоматического включения правильных директив и элементов div для отображения различных ошибок проверки:
В этом случае вам определенно необходим доступ к области (поскольку именно там хранятся ваши проверки), и вам придется скомпилировать дополнения вручную, опять же будьте осторожны, чтобы не скомпилировать что-либо дважды. (в качестве примечания, вам нужно будет установить имя для тега формы, содержащего форму (здесь я предполагаю theForm), и получить к нему доступ в связи с iElement.parent (). controller ('form'). $ name) ,
В этом случае нет смысла писать функцию компиляции. Ссылка действительно то, что вы хотите. Шаги будут:
Вот так:
Конечно, вы можете скомпилировать вложенные элементы один за другим, чтобы не беспокоиться о дублирующей обработке директив ng при повторной компиляции элемента верхнего уровня.
Последнее замечание по этому сценарию: я подразумевал, что вы будете выдавать определение проверок с сервера, и в моем примере я показал их как данные, уже находящиеся в области действия. Я оставляю читателю в качестве упражнения выяснить, как можно справиться с необходимостью извлечения этих данных из REST API (подсказка: отложенная компиляция).
СЦЕНАРИЙ 3: двусторонняя привязка данных по ссылке
Конечно, наиболее распространенное использование ссылки - просто подключить двустороннюю привязку данных через watch / apply. Большинство директив попадают в эту категорию, поэтому они адекватно рассматриваются в других местах.
источник
Из документов:
Поэтому, по крайней мере, в некоторых случаях эти две фазы существуют отдельно в качестве оптимизации.
От @ UmurKontacı :
источник
DOM
преобразование, это должно быть,compile
если вы хотите добавить некоторые функции, изменения поведения, это должно быть вlink
.Это из разговора Миско о директивах. http://youtu.be/WqmeI5fZcho?t=16m23s
источник
Немного опоздал с веткой. Но в интересах будущих читателей:
Я наткнулся на следующее видео, которое очень хорошо объясняет компиляцию и линковку в Angular JS:
https://www.youtube.com/watch?v=bjFqSyddCeA
Было бы нежелательно копировать / печатать весь контент здесь. Я сделал пару скриншотов из видео, которые объясняют каждый этап фаз компиляции и линковки:
Второй скриншот немного сбивает с толку. Но, если мы будем следовать пошаговой нумерации, это будет довольно просто.
Первый цикл: «Компиляция» выполняется в первую очередь для всех директив.
Второй цикл: «Контроллер» и «Pre-Link» выполняется (только один за другим) Третий цикл: «Post-Link» выполняется в обратном порядке (начиная с самого внутреннего)
Ниже приведен код, который демонстрирует вышеуказанное:
ОБНОВИТЬ:
Вторая часть того же видео доступна здесь: https://www.youtube.com/watch?v=1M3LZ1cu7rw. В простом примере видео объясняется, как модифицировать DOM и обрабатывать события во время процесса компиляции и компоновки в Angular JS. ,
источник
compile
иpost
для изменения DOM до того, как он будет измененtemplate
частично из директивы поставщика.Две фазы: компиляция и ссылка
Обобщение:
Пройдите по дереву DOM, ища директивы (элементы / атрибуты / классы / комментарии). Каждая компиляция директивы может изменять свой шаблон или модифицировать его содержимое, которое еще не было скомпилировано. Как только директива сопоставлена, она возвращает функцию связывания, которая используется на более позднем этапе для связывания элементов. В конце фазы компиляции у нас есть список скомпилированных директив и соответствующих им функций связывания.
Ссылка на сайт:
Когда элемент связан, дерево DOM нарушается в его точке ветвления в дереве DOM, а содержимое заменяется скомпилированным (и связанным) экземпляром шаблона. Исходный смещенный контент либо удаляется, либо, в случае включения, повторно связывается обратно в шаблон. При включении две части соединяются друг с другом (вроде цепочки, с частью шаблона в середине). Когда вызывается функция ссылки, шаблон уже был связан с областью действия и добавлен как дочерний элемент элемента. Функция link - это ваша возможность дополнительно манипулировать DOM и прослушивать изменения настроек.
источник
Этот вопрос старый, я хотел бы сделать краткое резюме, которое может помочь:
источник