Spec-Zone.ru › Angular.js 1.4

Улучшить эту документацию Просмотреть исходный код $compile

  1. $compileProvider
  2. сервис в модуле ng

Компилирует строку HTML или DOM в шаблон и создаёт функцию шаблона, которая затем может быть использована для связывания scope и шаблона вместе.

Компиляция — это процесс обхода дерева DOM и сопоставления элементов DOM с директивами.

Примечание: Этот документ — подробная справка по всем параметрам директивы. Для знакомства с директивами и примерами их использования в общих случаях обратитесь к руководству по директивам.

Подробный API директивы

Существует много различных параметров для директивы.

Различие заключается в возвращаемом значении функции фабрики. Вы можете либо вернуть «Объект определения директивы» (см. ниже), который определяет свойства директивы, либо просто функцию postLink (все остальные свойства будут иметь значения по умолчанию).

Рекомендация: Рекомендуется использовать форму «объекта определения директивы».

Вот пример директивы, объявленной с помощью Объекта определения директивы:

var myModule = angular.module(...);

myModule.directive('directiveName', function factory(injectables) {
  var directiveDefinitionObject = {
    priority: 0,
    template: '<div></div>', // or // function(tElement, tAttrs) { ... },
    // or
    // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
    transclude: false,
    restrict: 'A',
    templateNamespace: 'html',
    scope: false,
    controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
    controllerAs: 'stringIdentifier',
    bindToController: false,
    require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
    compile: function compile(tElement, tAttrs, transclude) {
      return {
        pre: function preLink(scope, iElement, iAttrs, controller) { ... },
        post: function postLink(scope, iElement, iAttrs, controller) { ... }
      }
      // or
      // return function postLink( ... ) { ... }
    },
    // or
    // link: {
    //  pre: function preLink(scope, iElement, iAttrs, controller) { ... },
    //  post: function postLink(scope, iElement, iAttrs, controller) { ... }
    // }
    // or
    // link: function postLink( ... ) { ... }
  };
  return directiveDefinitionObject;
});
Примечание: Любые не указанные параметры будут использовать значение по умолчанию. Значения по умолчанию показаны ниже.

Следовательно, вышесказанное можно упростить следующим образом:

var myModule = angular.module(...);

myModule.directive('directiveName', function factory(injectables) {
  var directiveDefinitionObject = {
    link: function postLink(scope, iElement, iAttrs) { ... }
  };
  return directiveDefinitionObject;
  // or
  // return function postLink(scope, iElement, iAttrs) { ... }
});

Объект определения директивы

Объект определения директивы предоставляет инструкции для компилятора. Атрибуты:

multiElement

Когда это свойство установлено в true, HTML-компилятор соберет узлы DOM между узлами с атрибутами directive-name-start и directive-name-end, и сгруппирует их вместе как элементы директивы. Рекомендуется использовать эту функцию для директивы, которая не является чисто поведенческой (например, ngClick), и которая не манипулирует и не заменяет дочерние узлы (например, ngInclude).

priority

Когда несколько директивы определены для одного элемента DOM, иногда необходимо указать порядок применения директивы. Свойство priority используется для сортировки директивы перед вызовом их функций compile. Приоритет определяется как число. Директивы с большим числовым priority компилируются первыми. Функции пред-связывания также выполняются в порядке приоритета, но функции пост-связывания выполняются в обратном порядке. Порядок директивы с одинаковым приоритетом не определён. По умолчанию приоритет 0.

terminal

Если установлено в true, то текущая priority будет последним набором директивы, который будет выполнен (любые директивы в текущем приоритете все равно будут выполнены, поскольку порядок выполнения с одинаковым priority не определён). Обратите внимание, что выражения и другие директивы, используемые в шаблоне директивы, также будут исключены из выполнения.

scope

Свойство scope может быть true, объектом или ложным значением:

  • ложное: Для директивы не будет создано scope. Директива будет использовать scope своего родителя.

  • true: Для элемента директивы будет создан новый дочерний scope, который прототипно наследуется от своего родителя. Если несколько директивы в одном элементе требуют нового scope, то создаётся только один новый scope. Правило нового scope не применяется к корню шаблона, так как корень шаблона всегда получает новый scope.

  • {...} (объект хэш): Для элемента директивы создаётся изолированный scope. Изолированный scope отличается от обычного scope тем, что он не прототипно наследуется от своего родительского scope. Это полезно при создании повторно используемых компонентов, которые не должны случайно считывать или изменять данные в родительском scope.

Объект-хэш изолированного scope определяет набор локальных свойств scope, полученных из атрибутов элемента директивы. Эти локальные свойства полезны для алиасирования значений для шаблонов. Ключи в объекте хэш соответствуют имени свойства в изолированном scope; значения определяют, как свойство связано с родительским scope, через соответствующие атрибуты в элементе директивы:

  • @ или @attr — связывают локальное свойство scope со значением атрибута DOM. Результат всегда является строкой, так как атрибуты DOM являются строками. Если имя attr не указано, то предполагается, что имя атрибута такое же, как локальное имя. Учитывая <my-component my-attr="hello {{name}}"> и определение изолированного scope scope: { localName:'@myAttr' }, свойство scope директивы localName будет отражать интерполированное значение hello {{name}}. При изменении атрибута name изменится и свойство localName в scope директивы. Значение name считывается из родительского scope (не из scope директивы).

  • = или =attr — устанавливает двустороннюю привязку между локальным свойством scope и выражением, переданным через атрибут attr. Выражение вычисляется в контексте родительского scope. Если имя attr не указано, то предполагается, что имя атрибута такое же, как локальное имя. Учитывая <my-component my-attr="parentModel"> и определение изолированного scope scope: { localModel: '=myAttr' }, свойство localModel в scope директивы будет отражать значение parentModel в родительском scope. Изменения в parentModel будут отражены в localModel и наоборот. Необязательные атрибуты должны быть помечены как такие с вопросительным знаком: =? или =?attr. Если выражение привязки не присваиваемо, или если атрибут не является необязательным и не существует, при обнаружении изменений локального значения будет брошено исключение ($compile:nonassign), так как будет невозможно синхронизировать их обратно с родительским scope. По умолчанию используется метод $watch для отслеживания изменений, а проверка равенства основана на идентичности объекта. Однако, если в качестве выражения привязки передаётся объект-литерал или массив-литерал, проверка равенства выполняется по значению (с использованием функции angular.equals). Также можно отслеживать вычисленное значение поверхностно с помощью $watchCollection: используйте =* или =*attr (=*? или =*?attr если атрибут является необязательным).

  • & или &attr — предоставляет способ выполнения выражения в контексте родительского scope. Если имя attr не указано, то предполагается, что имя атрибута такое же, как локальное имя. Учитывая <my-component my-attr="count = count + value"> и определение изолированного scope scope: { localFn:'&myAttr' }, свойство изолированного scope localFn будет указывать на оберточную функцию для выражения count = count + value. Часто желательно передавать данные из изолированного scope через выражение в родительский scope. Это можно сделать, передав карту имён локальных переменных и их значений в функцию-обёртку выражения. Например, если выражение increment(amount), то мы можем указать значение amount, вызвав localFn как localFn({amount: 22}).

В общем случае возможно применить более одной директивы к одному элементу, но могут быть ограничения в зависимости от типа scope, требуемого директивами. Следующие пункты помогут объяснить эти ограничения. Для простоты рассматриваются только две директивы, но это также применимо для нескольких директивы:

  • без scope + без scope => Две директивы, которые не требуют своего scope, будут использовать scope своего родителя
  • дочерний scope + без scope => Обе директивы будут совместно использовать один дочерний scope
  • дочерний scope + дочерний scope => Обе директивы будут совместно использовать один дочерний scope
  • изолированный scope + без scope => Директива с изолированным scope будет использовать свой созданный изолированный scope. Другая директива будет использовать scope своего родителя
  • изолированный scope + дочерний scope => Не сработает! Только один scope может быть связан с одним элементом. Поэтому эти директивы не могут быть применены к одному элементу.
  • изолированный scope + изолированный scope => Не сработает! Только один scope может быть связан с одним элементом. Поэтому эти директивы не могут быть применены к одному элементу.

bindToController

Это свойство используется для привязки свойств scope непосредственно к контроллеру. Это может быть либо true , либо объект хэш с тем же форматом, что и свойство scope . Кроме того, должен быть задан псевдоним контроллера, либо с помощью controllerAs: 'myAlias' , либо указанием псевдонима в определении контроллера: controller: 'myCtrl as myAlias'.

Когда для директивы используется изолированный scope (см. выше), bindToController: true позволит компоненту привязать свои свойства к контроллеру, а не к scope. Когда контроллер инициализируется, начальные значения привязок изолированного scope уже доступны.

Также возможно установить bindToController в объект хэш с тем же форматом, что и свойство scope. Это настроит привязки scope к контроллеру напрямую. Обратите внимание, что scope все равно может быть использован для определения типа создаваемого scope. По умолчанию scope не создаётся. Используйте scope: {} для создания изолированного scope (полезно для компонентных директивы).

Если оба bindToController и scope определены и имеют объекты хэш, bindToController переопределяет scope.

controller

Конструктор контроллера. Контроллер инициализируется перед фазой пред-связывания и может быть доступен другим директивам (см. атрибут require). Это позволяет директивам общаться друг с другом и дополнять поведение друг друга. Контроллер инжектируется (и поддерживает нотацию скобок) со следующими локалями:

  • $scope - Текущий область, связанная с элементом
  • $element - Текущий элемент
  • $attrs - Текущий объект атрибутов для элемента
  • $transclude - Функция трансклюдирования, предварительно привязанная к правильной области трансклюдирования: function([scope], cloneLinkingFn, futureParentElement).
    • scope: необязательный аргумент для переопределения области.
    • cloneLinkingFn: необязательный аргумент для создания клонов исходного трансклюдированного содержимого.
    • futureParentElement:
      • определяет родительский элемент, в который cloneLinkingFn добавит клонированные элементы.
      • по умолчанию: $element.parent() соответственно $element для transclude:'element' соответственно transclude:true.
      • требуется только для трансклюдирований, которые могут содержать не HTML-элементы (например, SVG-элементы) и когда передаётся cloneLinkinFn, так как эти элементы необходимо создавать и клонировать особым способом, когда они определены вне своих обычных контейнеров (например, как <svg>).
      • См. также свойство directive.templateNamespace.

require

Требует другую директиву и инжектирует её контроллер в качестве четвёртого аргумента в функцию связывания. require принимает строковое имя (или массив строк) директивы(директив), которые нужно передать. Если используется массив, то инжектируемый аргумент будет массивом в соответствующем порядке. Если такая директива не найдена или у неё нет контроллера, то возникает ошибка (если не указана функция связывания, в этом случае проверка на ошибки пропускается). Имя может быть префиксвано:

  • (без префикса) - Найти требуемый контроллер на текущем элементе. Выбросить ошибку, если не найден.
  • ? - Попытаться найти требуемый контроллер или передать null в функцию link при отсутствии.
  • ^ - Найти требуемый контроллер, перебирая элемент и его родительские элементы. Выбросить ошибку, если не найден.
  • ^^ - Найти требуемый контроллер, перебирая родительские элементы элемента. Выбросить ошибку, если не найден.
  • ?^ - Попытаться найти требуемый контроллер, перебирая элемент и его родительские элементы, или передать null в функцию link при отсутствии.
  • ?^^ - Попытаться найти требуемый контроллер, перебирая родительские элементы элемента, или передать null в функцию link при отсутствии.

controllerAs

Имя идентификатора для ссылки на контроллер в области директивы. Это позволяет ссылаться на контроллер из шаблона директивы. Это особенно полезно, когда директива используется как компонент, т.е. с областью isolate. Также возможно использовать его в директиве без области isolate / new, но необходимо учитывать, что ссылка controllerAs может перезаписать свойство, которое уже существует в родительской области.

restrict

Строка подмножества EACM, которая ограничивает директиву определенным стилем объявления. Если опущено, используются значения по умолчанию (элементы и атрибуты).

  • E - Имя элемента (по умолчанию): <my-directive></my-directive>
  • A - Атрибут (по умолчанию): <div my-directive="exp"></div>
  • C - Класс: <div class="my-directive: exp;"></div>
  • M - Комментарий: <!-- directive: my-directive exp -->

templateNamespace

Строка, представляющая тип документа, используемый разметкой в шаблоне. AngularJS нуждается в этой информации, так как эти элементы необходимо создавать и клонировать особым способом, когда они определены вне своих обычных контейнеров, таких как <svg> и <math>.

  • html - Все корневые узлы в шаблоне — HTML. Корневые узлы также могут быть верхнеуровневыми элементами, такими как <svg> или <math>.
  • svg - Корневые узлы в шаблоне — SVG-элементы (исключая <math>).
  • math - Корневые узлы в шаблоне — MathML-элементы (исключая <svg>).

Если templateNamespace не указано, то пространство имён считается html.

template

HTML-разметка, которая может:

  • Заменить содержимое элемента директивы (по умолчанию).
  • Заменить сам элемент директивы (если replace — ИСТИНА — УСТАРЕЛО).
  • Обернуть содержимое элемента директивы (если transclude — ИСТИНА).

Значение может быть:

  • Строкой. Например, <div red-on-hover>{{delete_str}}</div>.
  • Функцией, которая принимает два аргумента tElement и tAttrs (описаны в API-функции compile ниже) и возвращает строковое значение.

templateUrl

Это аналогично template, но шаблон загружается из указанного URL-адреса асинхронно.

Так как загрузка шаблона асинхронна, компилятор приостановит компиляцию директив в этом элементе до тех пор, пока шаблон не будет решён. Тем временем он продолжит компиляцию и связывание соседних и родительских элементов, как если бы этот элемент не содержал никаких директив.

Компилятор не приостанавливает всю компиляцию, чтобы подождать загрузки шаблонов, потому что это приведет к «зависанию» всего приложения до тех пор, пока все шаблоны не будут загружены асинхронно — даже в случае, если только одна глубоко вложенная директива имеет templateUrl.

Загрузка шаблона асинхронна даже в том случае, если шаблон был предварительно загружен в $templateCache

Вы можете указать templateUrl как строку, представляющую URL-адрес, или как функцию, которая принимает два аргумента tElement и tAttrs (описанные в API-функции compile ниже) и возвращает строковое значение, представляющее URL-адрес. В любом случае URL-адрес шаблона передается через $sce.getTrustedResourceUrl.

replace ([УСТАРЕЛО!], будет удалено в следующей основной версии — т.е. v2.0)

указывает, что должен заменить шаблон. По умолчанию false.

  • true - шаблон заменит элемент директивы.
  • false - шаблон заменит содержимое элемента директивы.

Процесс замены мигрирует все атрибуты/классы из старого элемента в новый. См. Руководство по директивам для примера.

Существует очень мало сценариев, где требуется замена элементов для работы приложения, основной из них — это использование переиспользуемых пользовательских компонентов в контекстах SVG (потому что SVG не работает с пользовательскими элементами в дереве DOM).

transclude

Извлечь содержимое элемента, где появляется директива, и сделать его доступным для директивы. Содержимое компилируется и предоставляется директиве в качестве функции трансклюдирования. См. раздел Трансклюдирование ниже.

Существует два типа трансклюдирования в зависимости от того, хотите ли вы трансклюдировать только содержимое элемента директивы или весь элемент:

  • true - трансклюдировать содержимое (т.е. дочерние узлы) элемента директивы.
  • 'element' - трансклюдировать весь элемент директивы, включая любые директивы в этом элементе, которые определены с более низким приоритетом, чем эта директива. При использовании свойство template игнорируется.

compile

function compile(tElement, tAttrs, transclude) { ... }

Функция компиляции обрабатывает преобразование шаблона DOM. Поскольку большинство директив не выполняют преобразование шаблона, она часто не используется. Функция компиляции принимает следующие аргументы:

  • tElement - элемент шаблона — Элемент, где была объявлена директива. Безопасно выполнять преобразование шаблона только на элементе и дочерних элементах.

  • tAttrs - атрибуты шаблона — Нормализованный список атрибутов, объявленных в этом элементе, общих для всех функций компиляции директив.

  • transclude - [УСТАРЕЛО!] Функция связывания трансклюдирования: function(scope, cloneLinkingFn)

Примечание: Экземпляр шаблона и экземпляр связывания могут быть разными объектами, если шаблон был клонирован. По этой причине не безопасно выполнять какие-либо действия, кроме преобразований DOM, которые применяются ко всем клонированным узлам DOM внутри функции компиляции. В частности, регистрация обработчиков событий DOM должна выполняться в функции связывания, а не в функции компиляции.
Примечание: Функция компиляции не может обрабатывать директивы, которые рекурсивно используют себя в своих шаблонах или функциях компиляции. Компиляция этих директив приводит к бесконечному циклу и ошибкам переполнения стека. Этого можно избежать, вручную используя $compile в функции postLink для императивной компиляции шаблона директивы вместо полагания на автоматическую компиляцию шаблона посредством объявления template или templateUrl или ручной компиляции внутри функции компиляции.
Примечание: Функция transclude, которая передается функции компиляции, устарела, так как она, например, не знает о правильной внешней области. Используйте вместо неё функцию трансклюдирования, которая передается функции связывания.

Функция компиляции может возвращать значение, которое может быть либо функцией, либо объектом.

  • возвращение (послесвязывающей) функции — эквивалентно регистрации функции связывания через свойство link объекта конфигурации, когда функция компиляции пустая.

  • возвращение объекта с зарегистрированными функцией(ями) через свойства pre и post — позволяет управлять тем, когда функция связывания должна вызываться во время фазы связывания. См. информацию о функциях предварительного и последующего связывания ниже.

link

Это свойство используется только если свойство compile не определено.

function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }

Функция связывания отвечает за регистрацию обработчиков событий DOM и обновление DOM. Она выполняется после клонирования шаблона. Именно здесь будет размещена большая часть логики директивы.

  • scope - Область видимости - Область видимости, используемая директивой для регистрации наблюдателей.

  • iElement - элемент экземпляра - Элемент, в котором должна использоваться директива. Безопасно изменять потомков элемента только в функции postLink, так как потомки уже связаны.

  • iAttrs - атрибуты экземпляра - Нормализованный список атрибутов, объявленных в этом элементе, общий для всех функций связывания директивы.

  • controller - экземпляры требуемого контроллера директивы - Экземпляры разделяются между всеми директивами, что позволяет им использовать контроллеры как канал связи. Точное значение зависит от свойства require директивы:

    • не требуется контроллер(ы): собственный контроллер директивы или undefined, если его нет
    • string: экземпляр контроллера
    • array: массив экземпляров контроллеров

    Если требуемый контроллер не найден, а он необязателен, экземпляр null, в противном случае выбрасывается ошибка Отсутствует требуемый контроллер.

    Обратите внимание, что вы также можете потребовать собственный контроллер директивы — он будет доступен как любой другой контроллер.

  • transcludeFn - функция связывания транклюзии, предварительно привязанная к правильной области видимости транклюзии. Это то же самое, что и параметр $transclude контроллеров директивы, см. там подробности. function([scope], cloneLinkingFn, futureParentElement).

Функция предварительного связывания

Выполняется до связывания дочерних элементов. Небезопасно выполнять преобразование DOM, так как функция связывания компилятора не сможет найти правильные элементы для связывания.

Функция пост-связывания

Выполняется после связывания дочерних элементов.

Обратите внимание, что дочерние элементы, содержащие директивы templateUrl , не будут скомпилированы и связаны, так как они ожидают загрузки шаблона асинхронно, и их собственная компиляция и связывание приостановлены до тех пор, пока это не произойдёт.

Безопасно выполнять преобразование DOM в функции пост-связывания для элементов, которые не ожидают разрешения своих асинхронных шаблонов.

Транклюзия

Транклюзия — это процесс извлечения набора элементов DOM из одной части DOM и их копирования в другую часть DOM с сохранением их связи с исходной областью видимости AngularJS, из которой они были взяты.

Транклюзия используется (часто с ngTransclude) для вставки исходного содержимого элемента директивы в указанное место в шаблоне директивы. Преимущество транклюзии по сравнению с ручным перемещением элементов DOM заключается в том, что содержимое транклюзии имеет доступ к свойствам области видимости, из которой оно было взято, даже если у директивы изолированная область видимости. См. Руководство по директивам.

Это позволяет виджету иметь частное состояние для своего шаблона, а содержимое транклюзии имеет доступ к исходной области видимости.

Примечание: При тестировании директивы транклюзии элемента вы не должны размещать директиву в корне фрагмента DOM, который компилируется. См. Тестирование директив транклюзии.

Функции транклюзии

Когда директива запрашивает транклюзию, компилятор извлекает её содержимое и предоставляет функцию транклюзии контроллеру директивы в функцию link и controller. Эта функция транклюзии — это специальная функция связывания, которая вернёт скомпилированное содержимое, связанное с новой областью видимости транклюзии.

Если вы просто используете ngTransclude, то вам не нужно беспокоиться об этой функции, так как ngTransclude позаботится об этом за вас.

Если вы хотите вручную управлять вставкой и удалением транклюдированного содержимого в своей директиве, то вам необходимо использовать эту функцию транклюзии. При вызове функции транклюзии она возвращает объект jqLite/JQuery, содержащий скомпилированный DOM, связанный с правильной областью видимости транклюзии.

При вызове функции транклюзии вы можете передать функцию прикрепления клона. Эта функция принимает два параметра, function(clone, scope) { ... }, где clone — свежая скомпилированная копия вашего транклюдированного содержимого, а scope — вновь созданная область видимости транклюзии, к которой привязан клон.

Рекомендации по лучшему стилю: Всегда предоставляйте функцию cloneFn (функцию прикрепления клона), когда вы вызываете функцию транклюзии, так как вы получаете свежий клон исходного DOM и также получаете доступ к новой области видимости транклюзии.

Обычной практикой является прикрепление транклюдированного содержимого (clone) к DOM внутри вашей функции прикрепления клона:

var transcludedContent, transclusionScope;

$transclude(function(clone, scope) {
  element.append(clone);
  transcludedContent = clone;
  transclusionScope = scope;
});

Позже, если вы хотите удалить транклюдированное содержимое из вашего DOM, вам также необходимо уничтожить связанную область видимости транклюзии:

transcludedContent.remove();
transclusionScope.$destroy();
Рекомендации по лучшему стилю: Если вы намерены добавлять и удалять транклюдированное содержимое вручную в своей директиве (вызвать функцию транклюзии для получения DOM и вызвать element.remove() для его удаления), то вы также несёте ответственность за вызов $destroy для области видимости транклюзии.

Встроенные директивы манипулирования DOM, такие как ngIf, ngSwitch и ngRepeat, автоматически уничтожают свои клоны транклюзии при необходимости, поэтому вам не нужно об этом беспокоиться, если вы просто используете ngTransclude для вставки транклюзии в свою директиву.

Области видимости транклюзии

При вызове функции транклюзии возвращается фрагмент DOM, предварительно связанный с областью видимости транклюзии. Эта область видимости является специальной, поскольку является дочерним элементом области видимости директивы (и, следовательно, уничтожается при уничтожении области видимости директивы), но она наследует свойства области видимости, из которой она была взята.

Например, рассмотрим директиву, использующую транклюзию и изолированную область видимости. Иерархия DOM может выглядеть так:

<div ng-app>
  <div isolate>
    <div transclusion>
    </div>
  </div>
</div>

Иерархия областей видимости $parent будет выглядеть так:

- $rootScope
  - isolate
    - transclusion

но области видимости будут наследоваться прототипически от разных областей видимости до их $parent.

- $rootScope
  - transclusion
- isolate

Атрибуты

Объект Атрибутов - передаётся в качестве параметра в функциях link() или compile(). Он имеет множество применений.

  • Доступ к нормализованным именам атрибутов: Такие директивы, как 'ngBind', могут быть выражены многими способами: 'ng:bind', data-ng-bind, или 'x-ng-bind'. Объект атрибутов позволяет получить нормализованный доступ к атрибутам.

  • Взаимодействие между директивами: Все директивы используют один и тот же экземпляр объекта атрибутов, что позволяет директивам использовать объект атрибутов для междирективного взаимодействия.

  • Поддержка интерполяции: Атрибуты интерполяции назначаются объекту атрибутов, что позволяет другим директивам считывать интерполированное значение.

  • Наблюдение за изменениями интерполированных атрибутов: Используйте $observe для наблюдения за изменениями значений атрибутов, содержащих интерполяцию (например, src="{{bar}}"). Это не только очень эффективно, но и единственный способ легко получить фактическое значение, потому что во время фазы связывания интерполяция ещё не была вычислена, и поэтому значение в это время установлено в undefined.

function linkingFn(scope, elm, attrs, ctrl) {
  // get the attribute value
  console.log(attrs.ngModel);

  // change the attribute
  attrs.$set('ngModel', 'new value');

  // observe changes to interpolated attribute
  attrs.$observe('ngModel', function(value) {
    console.log('ngModel has changed value to ' + value);
  });
}
Примечание: Обычно директивы регистрируются с помощью module.directive. Приведённый ниже пример иллюстрирует, как работает $compile.

Использование

$compile(element, transclude, maxPriority);

Аргументы

Параметр Тип Подробности
element stringDOMElement

Элемент или строка HTML для компиляции в функцию шаблона.

transclude function(angular.Scope, cloneAttachFn=)

Функция, доступная директивам — УСТАРЕВШАЯ.

Примечание: Передача функции transclude в функцию $compile устарела, так как она, например, не будет использовать правильную внешнюю область видимости. Пожалуйста, передайте функцию transclude как parentBoundTranscludeFn в функцию link вместо этого.
maxPriority number

Применить только директивы с приоритетом ниже заданного (влияет только на корневой(е) элемент(ы), а не на их потомков).

Возвращаемое значение

function(scope, cloneAttachFn=, options=)

функция link, используемая для привязки шаблона (элемента/дерева DOM) к области видимости. Где:

  • scope - Область видимости Scope для привязки.
  • cloneAttachFn - Если cloneAttachFn предоставлена, то функция link скопирует template и вызовет функцию cloneAttachFn, позволяя вызывающей стороне прикрепить клонированные элементы к документу DOM в соответствующем месте. Функция cloneAttachFn вызывается как:
    cloneAttachFn(clonedElement, scope) где:

    • clonedElement - это копия исходного element, переданного в компилятор.
    • scope - текущая область видимости, с которой работает функция link.
  • options - необъект с параметрами привязки. Если options предоставлен, то можно использовать следующие ключи для управления поведением привязки:

    • parentBoundTranscludeFn - функция transclude, предоставляемая директивам; если указана, она будет передана функциям link директивам, найденным в element во время компиляции.
    • transcludeControllers - объект с хешем, ключи которого соответствуют именам контроллеров, а значение — хеш с ключом instance, отображающим экземпляр контроллера; если задан, это позволит сделать контроллеры доступными директивам в compileNode:
      {
        parent: {
          instance: parentControllerInstance
        }
      }
      
    • futureParentElement - определяет родителя, к которому cloneAttachFn добавит клонированные элементы; необходимо только для transclude, которые могут содержать не html-элементы (например, SVG-элементы). См. также свойство directive.controller.

Вызов функции link возвращает элемент шаблона. Это либо исходный элемент, переданный, либо копия элемента, если cloneAttachFn предоставлен.

После привязки представление не обновляется до вызова $digest, который обычно автоматически выполняется Angular.

Если вам нужен доступ к связанному представлению, есть два способа:

  • Если вы не просите функцию link клонировать шаблон, создайте DOM-элемент(ы) до отправки их в компилятор и сохраните эту ссылку.

    var element = $compile('<p>{{total}}</p>')(scope);
    
  • если, с другой стороны, вам нужен клонированный элемент, ссылка на представление из исходного примера не будет указывать на копию, а на исходный шаблон, который был скопирован. В этом случае вы можете получить доступ к копии через cloneAttachFn:

    var templateElement = angular.element('<p>{{total}}</p>'),
        scope = ....;
    
    var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
      //attach the clone to DOM document at the right place
    });
    
    //now we have reference to the cloned DOM via `clonedElement`
    

Дополнительную информацию о работе компилятора см. в разделе Компилятор Angular HTML руководства разработчика.

© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.4.14/docs/api/ng/service/$compile

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API