Что такое директивы в angular
Директивы в Angularjs для начинающих. Часть 1
Как писать директивы?
Директивы в Angularjs задаются вместе с другими конфигурациями модуля следующим образом:
При этом есть два варианта их объявления. Простой и более мощный длинный варианты.
Простой вариант создания директивы
Для того, чтобы написать директиву, которая будет вызываться при указании в HTML разметке, в простейшем случае вам нужно задать некую функцию (она называется Связующей Linking, но об этом чуть позже), возвращаемую фабрикой:
Всё. Директива в примитивном виде у нас готова. Можно переходить к более развернутой форме.
Развернутый вариант
В своей полноценной форме задание директивы выглядит следующим образом:
Все эти свойства довольно тесно друг с другом связаны и переплетены. И для того, чтобы было проще в этом разобраться, их лучше рассматривать некими смысловыми группами.
Link и Compile
Метод Link это та самая функция, которую возвращала фабрика директивы в короткой версии. Здесь надо понять, что в Angularjs процесс компиляции разбит на два этапа:
И при этом как в простейшей версии, так и в расширенной метод Link правильно будет называть postLink, поскольку он выполняется после того, как переменные уже сопоставлены. Рассмотрим примеры.
Сперва, я предлагаю переписать пример простой директивы на манер расширенной.
То есть всё, действительно, работает по-прежнему. Теперь можно усложнить задачу и сделать так, чтобы наша фраза выводилась не посредством прямого взаимодействия с DOM element.text(. ), а внутри директивы interpolate «<<>>»:
В примере выше директива habraHabrNotwork не будет работать корректно, поскольку мы вставляем директиву «<<>>» с переменными в postLink, то есть, когда уже выполнены компиляця и линкование. Иными словами Angularjs даже не знает, что «<<>>» это директива, которая подлежит исполнению.
Другое дело, вторая директива. Там всё на своем месте, мы вставляем шаблон «<<"+attrs.habraHabrNotwork+"+"+attrs.habra+">>» до компиляции, и он успешно проходит рендеринг.
Остановимся немного на методе compile. Он может возвращать, как функцию postLink, так и объект с двумя параметрами: pre и post. Где pre и post это методы preLink и postLink соответственно. Из названия методов может показаться, что речь идет о методах до и после Linkа. Но это не совсем так, эти функции выполняются до и после Link а детей директивы в DOM. На примере:
На этом предлагаю сделать паузу. Если тема интересная, в ближайшие дни постараюсь написать продолжение про области видимости и шаблоны.
Директивы в AngularJS
Директивы — это ключевая особенность AngularJS. С помощью директив можно добавлять новое поведение существующим HTML элементам, можно создавать новые компоненты. Примерами директив, добавляющих новое поведения для существующих HTML элементов, могут служить input, select, textarea в связке с ngModel, required и т.п. Перечисленные директивы в основном связаны с валидацией форм в AngularJS. Но тема валидации заслуживает отдельной статьи.
Директивы можно и нужно использовать для повышения модульности вашего приложения, выделения обособленной функциональности в компоненты, в том числе и для повторного использования.
Если вы разрабатываете приложение на AngularJS и не создаете директивы, то это уже само по себе немного настораживает. Либо ваше приложение достаточно простое и уложилось в стандартные возможности AngularJS, либо, скорее всего, что-то не так с архитектурой вашего приложения. А если у вас при этом есть работа с DOM-ом в контроллерах или сервисах, то вам однозначно надо разбираться с темой создания директив, т.к. манипуляций с DOM-ом не должно быть нигде, кроме директив.
В данной статье я постараюсь рассмотреть процесс создания собственных директив на нескольких примерах.
Хорошим примером создания директив могут служить репозитории команды AngularUI. В эту команду входят разработчики, не являющиеся сотрудниками Google, но очень хорошо зарекомендовавшие себя в списке рассылки и на stackoverflow. Насколько я могу судить, они создают production-ready компоненты с настройками, покрывающими большую часть вариантов использования. У меня тоже есть репозиторий, в который я выкладываю некоторые свои наработки. Но у меня немного другой подход. Мне больше нравится делать директивы под конкретные варианты использования. AngularJS очень лаконичен. Меньше кода => лучше читаемость => проще поддержка и изменение. Зачем тогда создавать «монструозные» компоненты с кучей настроек? Поэтому рассматривайте эти директивы как отправную точку для создания своих собственных под конкретные нужды. Еще за примерами можно пойти на сайт ngmodules.org, возможно, он сможет стать каталогом различных компонентов для AngularJS.
Итак, базовым документом для разработки своих директив является статья Directives из Developer Guide. Там все расписано очень хорошо и подробно. К этому документу придется возвращаться еще не раз.
Директива-обертка для Tooltip-а из Twitter Bootstrap
Использоваться будет примерно так:
За названием директивы идет фабричная функция, которая должна вернуть описание директивы. В общем случае описание представляет собой объект, полный список полей которого приведен в документации. Но существует упрощенный вариант, когда можно вернуть только postLink функцию. В этому случае директива в дальнейшем может использоваться только как атрибут какого-либо HTML элемента. В этом примере как раз использован упрощенный вариант создания директивы.
Последовательность выполнения фаз для иерархической структуры наглядно показана здесь.
Директива для подсветки кода
‘); pre.append(prettyPrintOne(escape(elem.html().slice(1)), undefined, true)); elem.replaceWith(pre); > >; >);
Директива для подсветки кода с использованием google-code-prettify.
Необходимо, чтобы внутреннее содержимое этой директивы не компилировалось и не линковалось, а просто было обработано google-code-prettify.
Данная директива уже реализована через конфигурационный объект. Рассмотрим директиву построчно.
Директива может использоваться как элемент и как атрибут. В общем случае варианты применения кодируются как ‘EACM’. Можно создать директиву, которая может использоваться как элемент ‘E’, атрибут ‘A’, класс ‘C’, комментарий ‘M’.
Означает, что приоритет на котором объявлена эта директива будет последним приоритетом исполнения. Т.е. будут выполнены только директивы приоритетом выше и с таким же. С таким же приоритетом будут выполнены все директивы, т.к. в рамках одного приоритета порядок исполнения директив не определен.
На этапе компиляции мы извлекаем содержимое элемента, обрабатываем спецсимволы, заменяя их на мнемоники, результат обрабатываем google-code-prettify, обрамляем это все тегом pre и заменяем исходный элемент получившимся.
Вот еще интересные варианты директив, задействующих этап компиляции: ng-if, transclude into an attribute. Оставляйте еще примеры в комментариях, добавлю в пост.
uiPagination
Код достаточно длинный, поэтому сюда вставлять не буду.
Классическая директива с визуальным компонентом.
Ключевая особенность здесь — использование изолированной области видимости (scope).
Статья уже получается достаточно большой, поэтому я не буду подробно останавливаться на деталях и всех возможных вариантах. Они хорошо описаны в документации. Кроме того, рекомендую ознакомиться со статьей The Nuances of Scope Prototypal Inheritance (там хорошие визуализации).
В данном случае cur и total будут двунаправлено привязаны через одноименные атрибуты к области видимости, в которой используется директива, а display будет получать обновления через одноименный атрибут из той же области видимости.
uiGrid
Честно говоря, я все откладывал написание этой статьи, пока не напишу подобную директиву 🙂 Написал статью, смотрю, а она тут уже особо ничего не решает. Но раз уж написана, пусть будет как proof of concept. Можно, конечно, все настройки и через большой объект в атрибуте передавать как в ng-grid, но AngularJS может «круче», более декларативно. Поэтому подобный подход, мне кажется, более в духе AngularJS.
Пользовательские структурные директивы в Angular
Nov 13, 2020 · 3 min read
Что такое структурные директивы?
Angular — это платформа для создания мобильных и настольных веб-приложений. Присоединяйтесь к сообществу миллионов разработчиков…
Создание пользовательских структурных директив
Поговорим теперь о создании пользовательской директивы в приложении на Angular. Рассмотрим базовую реализацию структурной директивы.
Сцен а рий варианта использования: структурная директива применяется к контейнеру (например, div ). Передадим в эту директиву некоторое значение задержки. Содержимое контейнера будет отображаться только по истечении времени задержки, поэтому придётся отложить просмотр контейнера до истечения времени задержки. Обратимся теперь к коду, который для всего этого потребуется.
Посмотрите, как создаётся пользовательская структурная директива:
Создание структурной директивы без поведения
Применение директивы к элементу
На содержимое контейнера
This is the Template area
Теперь нужно обновить код, чтобы включить задержку в 1000 миллисекунд при отображении шаблона директивы. В нашем случае необходимо, чтобы тег h1 отображался по истечении указанного значения задержки.
Завершение кода директивы
Теперь внутри функции ngOnInit мы помещаем setTimeout и по истечении заданного времени встраиваем шаблон в указанный нами контейнер.
Это одна из простых реализаций структурной директивы в Angular. Вот как выполняется проект:
Директивы¶
Angular директивы используются для изменения внешнего вида или поведения DOM-элемента. Выделяют три типа директив:
Компоненты уже были разобраны ранее, поэтому в этой и следующей главах будут рассмотрены только структурные директивы и директивы атрибуты.
Несмотря на существующую классификацию, иногда бывают трудно однозначно определить принадлежность к группе, поскольку одна директива может совмещать в себе функционал сразу двух групп.
По умолчанию в Angular предусмотрен ряд встроенных директив. Рассмотрим самые популярные из них.
*ngFor¶
*ngFor используется для визуализации массива данных. Директива применяется к блоку HTML-кода, определяющего, как должны отображаться данные элемента массива. Далее Angular использует этот HTML как шаблон для всех последующих элементов в массиве.
Предположим, имеется следующий массив данных:
Отображение списка в шаблоне выглядит так:
В результате будет сгенерирован следующий HTML-код:
Angular *ngFor поддерживает ряд шаблонных переменных:
ngSwitch¶
ngSwitch эмулирует работу оператора switch применительно к шаблонам.
Angular директивы *ngSwitchCase и *ngSwitchDefault отображают указанный шаблон в зависимости от значения переданной ngSwitch переменной или шаблон по умолчанию, если ни один из описанных случаев не соответствует реальному значению.
ngStyle и ngClass¶
Объект стилей можно определить прямо в шаблоне, причем можно использовать выражения и условия.
Также директива может принимать массив со списком классов, которые необходимо применить к элементу.
Пользовательские структурные директивы в Angular
Что такое структурные директивы?
Angular — это платформа для создания мобильных и настольных веб-приложений. Присоединяйтесь к сообществу миллионов разработчиков…
Создание пользовательских структурных директив
Поговорим теперь о создании пользовательской директивы в приложении на Angular. Рассмотрим базовую реализацию структурной директивы.
Сценарий варианта использования: структурная директива применяется к контейнеру (например, div ). Передадим в эту директиву некоторое значение задержки. Содержимое контейнера будет отображаться только по истечении времени задержки, поэтому придётся отложить просмотр контейнера до истечения времени задержки. Обратимся теперь к коду, который для всего этого потребуется.
Посмотрите, как создаётся пользовательская структурная директива:
Создание структурной директивы без поведения
Применение директивы к элементу
На содержимое контейнера
This is the Template area
Теперь нужно обновить код, чтобы включить задержку в 1000 миллисекунд при отображении шаблона директивы. В нашем случае необходимо, чтобы тег h1 отображался по истечении указанного значения задержки.
Завершение кода директивы
Теперь внутри функции ngOnInit мы помещаем setTimeout и по истечении заданного времени встраиваем шаблон в указанный нами контейнер.
Это одна из простых реализаций структурной директивы в Angular. Вот как выполняется проект: