Мне нужно выполнить некоторые операции над областью действия и шаблоном. Кажется, что я могу сделать это либо в link
функции, либо в controller
функции (поскольку оба имеют доступ к области действия).
В каком случае я должен использовать link
функцию, а не контроллер?
angular.module('myApp').directive('abc', function($timeout) {
return {
restrict: 'EA',
replace: true,
transclude: true,
scope: true,
link: function(scope, elem, attr) { /* link function */ },
controller: function($scope, $element) { /* controller function */ }
};
}
Также я понимаю, что link
это не угловой мир. Таким образом, я могу использовать $watch
, $digest
и $apply
.
Какое значение имеет link
функция, когда у нас уже был контроллер?
javascript
angularjs
angularjs-directive
Югаль Джиндл
источник
источник
$watch
,$digest
и$apply
. »?link
мы не видим никакой угловой магии. т.е. нет двухсторонних привязок и т. д. Просто у нас есть доступный для использования API угловой.Ответы:
После моей первоначальной борьбы с
link
иcontroller
функциями и чтения довольно много о них, я думаю , что теперь у меня есть ответ.Сначала давайте поймем ,
Как угловые директивы работают в двух словах:
Мы начинаем с шаблона (в виде строки или загружается в строку)
var templateString = '<div my-directive>{{5 + 10}}</div>';
Теперь это
templateString
завернуто как угловой элементvar el = angular.element(templateString);
С
el
, теперь мы скомпилируем его,$compile
чтобы вернуть функцию ссылки .var l = $compile(el)
Вот что происходит,
$compile
проходит через весь шаблон и собирает все директивы, которые он распознает.link
функции собираются.link
функции оборачиваются в новуюlink
функцию и возвращаются какl
.Наконец, мы предоставляем
scope
функцию этой функцииl
(link), которая дополнительно выполняет функции обернутой ссылки с этимscope
и их соответствующими элементами.l(scope)
Это добавляет
template
новый узел кDOM
и вызывает,controller
который добавляет его часы в область, которая используется совместно с шаблоном в DOM.Сравнение компиляции против линии против контроллера :
Каждая директива компилируется только один раз, и функция связи сохраняется для повторного использования. Следовательно, если что-то применимо ко всем экземплярам директивы, ее следует выполнять внутри
compile
функции директивы .Теперь после компиляции у нас есть
link
функция, которая выполняется при подключении шаблона к DOM . Поэтому мы выполняем все, что является специфическим для каждого экземпляра директивы. Например: прикрепление событий , изменение шаблона в зависимости от области видимости и т. Д.Наконец, контроллер должен быть доступен для работы и реагирования, в то время как директива работает над
DOM
(после присоединения). Следовательно:(1) После настройки просмотра [ V ] (т.е. шаблон) со ссылкой.
$scope
наш [ M ] и$controller
наш [ C ] в MVC(2) Воспользуйтесь двухсторонним связыванием с $ scope , настроив часы.
(3)
$scope
Ожидается, что часы будут добавлены в контроллер, поскольку именно это отслеживает шаблон во время выполнения.(4) Наконец,
controller
также используется для связи между соответствующими директивами. (КакmyTabs
пример в https://docs.angularjs.org/guide/directive )(5) Это правда, что мы могли бы сделать все это и в
link
функции, но это касается разделения интересов .Поэтому, наконец, у нас есть следующее, которое идеально подходит для всех частей:
источник
Зачем нужны контроллеры
Разница между
link
иcontroller
вступает в игру, когда вы хотите вложить директивы в DOM и представить функции API из родительской директивы для вложенных.Из документов :
Допустим , вы хотите иметь две директивы
my-form
и ,my-text-input
и вы хотитеmy-text-input
директивы появляться только внутриmy-form
и больше нигде.В этом случае, вы будете говорить при определении директивы ,
my-text-input
что она требует контроллера отparent
элемента DOM с использованием требует аргумента, например:require: '^myForm'
. Теперь контроллер из родительского элемента будетinjected
вlink
функции в качестве четвертого аргумента, следующего$scope, element, attributes
. Вы можете вызывать функции на этом контроллере и взаимодействовать с родительской директивой.Более того, если такой контроллер не найден, возникнет ошибка.
Зачем вообще использовать ссылку
Нет реальной необходимости использовать
link
функцию, если вы определяете,controller
поскольку$scope
она доступна вcontroller
. Более того, при определении обоихlink
иcontroller
нужно соблюдать осторожность в отношении порядка вызова двух (controller
выполняется раньше).Однако, в соответствии с Angular-способом , большинство DOM-манипуляций и двухстороннего связывания
$watchers
обычно выполняются вlink
функции, а API для дочерних и$scope
манипуляций - вcontroller
. Это не сложное и быстрое правило, но это сделает код более модульным и поможет разделить задачи (контроллер будет поддерживатьdirective
состояние, аlink
функция будет поддерживатьDOM
внешние + привязки).источник
link
?controller
? Почему я хочу изобрести совершенно новую функцию, чтобы избежать определения контроллера?controller
Функция / объект представляет собой абстракцию модель-представление-контроллер (MVC). Хотя нет ничего нового, что можно написать о MVC, это все же самое значительное преимущество angular: разделить проблемы на более мелкие части. И это все, не более того, так что если вам нужно реагировать наModel
изменения, поступающие от человека,View
тоController
это тот человек, который должен выполнять эту работу.История о
link
функции отличается, она идет с другой точки зрения, чем MVC. И это действительно важно, когда мы хотим пересечь границыcontroller/model/view
(шаблона) .Давайте начнем с параметров, которые передаются в
link
функцию:Чтобы поместить
link
в контекст, мы должны упомянуть, что все директивы проходят через эти шаги процесса инициализации: Compile , Link . Выдержка из книги Брэда Грина и Шьяма Сешадри Angular JS :Фаза компиляции (родственная ссылка, давайте упомянем ее здесь, чтобы получить ясную картину):
На этом этапе Angular обходит DOM, чтобы определить все зарегистрированные директивы в шаблоне. Затем для каждой директивы она преобразует DOM на основе правил директивы (template, replace, transclude и т. Д.) И вызывает функцию compile, если она существует. Результатом является скомпилированная функция шаблона,
Фаза связи :
Хороший пример того, как использовать
link
можно найти здесь: Создание пользовательских директив . См. Пример: создание директивы, управляющей DOM , которая вставляет «дату-время» в страницу, обновляемую каждую секунду.Просто очень короткий фрагмент из этого богатого источника выше, демонстрирующий реальные манипуляции с DOM. Функция $ timeout подключена, а также очищается при вызове деструктора, чтобы избежать утечек памяти
источник
compiler
иlink
. Они спрашивают, почему,link
когда у нас это уже былоcontroller
controller
противlink
должны быть более ясными ...link
или вcontroller
.controller
иlink
относительно некрасиво. Итак, у угловой команды должна быть веская причина, а не просто вариант.