Spec-Zone.ru › Angular.js 1.2

Улучшить эту документацию Посмотреть исходный код $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',
    scope: false,
    controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
    controllerAs: 'stringAlias',
    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) { ... }
});

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

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

priority

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

terminal

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

scope

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

Если установлено в значение {} (хеш объекта), то создается новый «изолированный» контекст. Изолированный контекст отличается от обычного контекста тем, что он не наследоваться от родительского контекста. Это полезно при создании переиспользуемых компонентов, которые не должны случайно считывать или изменять данные в родительском контексте.

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

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

  • = или =attr — устанавливает двунаправленную привязку между локальным свойством контекста и свойством родительского контекста с именем, определенным через значение атрибута attr. Если имя атрибута не указано, предполагается, что имя атрибута совпадает с локальным именем. Учитывая <widget my-attr="parentModel"> и определение виджета scope: { localModel:'=myAttr' }, то свойство контекста виджета localModel будет отражать значение parentModel в родительском контексте. Любые изменения в parentModel будут отражаться в localModel, и любые изменения в localModel будут отражаться в parentModel. Если свойство родительского контекста не существует, будет выброшено исключение NON_ASSIGNABLE_MODEL_EXPRESSION. Вы можете избежать этого поведения, используя =? или =?attr, чтобы пометить свойство как необязательное.

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

controller

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

  • $scope — Текущий контекст, связанный с элементом
  • $element — Текущий элемент
  • $attrs — Текущий объект атрибутов для элемента
  • $transclude — Функция связывания транклюзии, предварительно привязанная к правильному контексту транклюзии. Контекст можно переопределить, передав необязательный первый аргумент. function([scope], cloneLinkingFn).

require

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

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

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 -->

template

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

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

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

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

templateUrl

То же самое, что и template, но шаблон загружается по указанному URL-адресу. Поскольку загрузка шаблона асинхронна, компиляция/связывание приостанавливается до тех пор, пока шаблон не загрузится.

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

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

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

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

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

transclude

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

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

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

compile

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

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

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

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

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

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

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

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

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

link

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

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

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

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

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

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

  • controller - экземпляр контроллера - Экземпляр контроллера, если хотя бы одна директива в элементе определяет контроллер. Контроллер используется всеми директивами, что позволяет директивам использовать контроллеры в качестве канала связи.

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

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

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

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

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

Атрибуты

Объект Атрибуты - передается в качестве параметра в функции 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);

Аргументы

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

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

transclude function(angular.Scope, cloneAttachFn=)

функция, доступная для директив.

maxPriority number

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

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

function(scope, cloneAttachFn=)

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

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

    • clonedElement - является клоном исходного element , переданного в компилятор.
    • scope - текущая область видимости, с которой работает функция связывания.

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

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

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

  • Если вы не просите функцию связывания клонировать шаблон, создайте 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.2.32/docs/api/ng/service/$compile

Spec-Zone.ru

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