Разница между функциями 'controller', 'link' и 'compile' при определении директивы
Некоторые места, кажется, используют функцию контроллера для логики директив, а другие используют связь. Пример вкладок на угловой домашней странице использует контроллер для одной и ссылку для другой директивы. Какая разница между двумя?
4 ответа
Я собираюсь немного расширить ваш вопрос, а также включить функцию компиляции.
функция компиляции - используется для манипулирования DOM шаблона (т. е. манипуляции с элементом tElement = template), следовательно, манипуляции, которые применяются ко всем клонам DOM шаблона, связанным с директивой. (Если вам также нужна функция ссылки (или функции ссылки до и после), и вы определили функцию компиляции, функция компиляции должна возвращать функцию (и) ссылки, потому что
'link'
атрибут игнорируется, если'compile'
атрибут определен.)Функция Link - обычно используется для регистрации обратных вызовов слушателя (т.е.
$watch
выражения в области видимости), а также обновление DOM (т. е. манипулирование iElement = отдельный элемент экземпляра). Это выполняется после того, как шаблон был клонирован. Например, внутри<li ng-repeat...>
, функция ссылки выполняется после<li>
шаблон (элемент) был клонирован (в элемент) для этого конкретного<li>
элемент.$watch
позволяет директиве получать уведомления об изменениях свойства области (область действия связана с каждым экземпляром), что позволяет директиве отображать обновленное значение экземпляра в DOM.функция контроллера - должна использоваться, когда другая директива должна взаимодействовать с этой директивой. Например, на домашней странице AngularJS директива pane должна добавить себя в область, поддерживаемую директивой tabs, следовательно, директива tabs должна определить метод контроллера (думаю API), к которому директива pane может обращаться / вызывать.
Для более подробного объяснения директив tabs и pane, и почему директива tabs создает функцию на своем контроллере, используяthis
(а не на$scope
), смотрите 'this' vs $scope в контроллерах AngularJS.
В общем, вы можете поставить методы, $watches
и т. д. в контроллер или директиву директивы. Сначала будет запущен контроллер, что иногда имеет значение (см. Эту скрипку, которая регистрирует, когда функции ctrl и link запускаются с двумя вложенными директивами). Как упоминал Джош в комментарии, вы можете захотеть поместить функции манипулирования областью в контроллер просто для согласованности с остальной частью фреймворка.
В дополнение к ответу Марка, функция компиляции не имеет доступа к области видимости, но функция ссылки имеет.
Я действительно рекомендую это видео; Написание директив Миско Хевери (отец AngularJS), где он описывает различия и некоторые приемы. (Разница между функцией компиляции и функцией ссылки на отметке 14:41 на видео).
- запуск кода перед компиляцией: используйте контроллер
- запуск кода после компиляции: используйте ссылку
Угловое соглашение: написать бизнес-логику в контроллере и манипулирование DOM в ссылке.
Помимо этого вы можете вызывать одну функцию контроллера из функции ссылки другой директивы. Например, у вас есть 3 пользовательских директивы
<animal>
<panther>
<leopard></leopard>
</panther>
</animal>
и вы хотите получить доступ к животным изнутри директивы "леопард".
http://egghead.io/lessons/angularjs-directive-communication будет полезно узнать о межправительственной связи
функция компиляции -
- вызывается перед контроллером и функцией связи.
- В функции компиляции у вас есть оригинальный шаблон DOM, так что вы можете вносить изменения в исходный DOM до того, как AngularJS создаст его экземпляр, и до того, как будет создана область действия.
- ng-repeat - отличный пример - оригинальный синтаксис является элементом шаблона, повторяющиеся элементы в HTML являются экземплярами
- Может быть несколько экземпляров элемента и только один элемент шаблона.
- Область еще не доступна
- Функция компиляции может возвращать функцию и объект
- возвращение функции (post-link) - эквивалентно регистрации функции связывания через свойство link объекта config, когда функция компиляции пуста.
- Возврат объекта с функцией (ями), зарегистрированной через свойства pre и post - позволяет вам контролировать, когда функция связывания должна вызываться во время фазы связывания. См. Информацию о функциях предварительной ссылки и последующей ссылки ниже.
синтаксис
function compile(tElement, tAttrs, transclude) { ... }
контроллер
- вызывается после функции компиляции
- объем доступен здесь
- могут быть доступны из других директив (см. атрибут require)
предварительная ссылка
Функция ссылки отвечает за регистрацию слушателей DOM, а также за обновление DOM. Это выполняется после того, как шаблон был клонирован. Именно здесь будет помещена большая часть директивной логики.
Вы можете обновить dom в контроллере, используя angular.element, но это не рекомендуется, так как элемент предоставляется в функции link
Функция предварительной ссылки используется для реализации логики, которая выполняется, когда angular js уже скомпилировал дочерние элементы, но до того, как какая-либо ссылка на запись дочернего элемента была вызвана
пост-ссылка
директива, которая имеет только функцию ссылки, angular рассматривает функцию как ссылку для публикации
сообщение будет выполнено после функции компиляции, контроллера и предварительной ссылки, поэтому это считается самым безопасным и стандартным местом для добавления вашей логики директивы