Автор оригинала: Christian Nwamba.
Директивы являются наиболее фундаментальной единицей угловых приложений. На самом деле самая подержанная единица, которая является компонентом, на самом деле является директивой. Компоненты являются высококачественными директивами с шаблонами и служат строительными блоками угловых приложений.
Как писать компоненты в угловых 2 – везде в Интернете, поэтому мы не говорим об этом сегодня. То, что мы будем изучать сегодня, является унциями 2-х годов; Типы, когда их использовать и как построить один для наших пользовательских потребностей.
Типы директив
Угловые 2 классифицирует директивы на 3 части:
- Директивы с шаблонами, известными как Составные части
- Директивы, которые создают и разрушают элементы DOM, известные как Структурные директивы
- Директивы, которые манипулируют DOM путем изменения поведения и внешности, известные как Директивы атрибутов
Компоненты – это то, с тем, как было введено угловые 2, так что нет необходимости говорить об этом. Мы можем идти вперед и обсудить атрибут и структурные директивы.
Директивы атрибутов
Директивы атрибутов, как и имя, применяются в качестве атрибутов к элементам. Они используются для манипулирования домом во всех видах различных способов, кроме как их создания или уничтожения их. Мне нравится называть их дириграммами для домочек.
Директивы в этих категориях могут помочь нам достичь одной из следующих задач:
- Применить условные стили и классы к элементам
Directives are awesome
- Скрыть и показывать элементы, условно (отличается от создания и уничтожения элементов)
Directives are awesome
- Динамически меняется поведение компонента на основе изменяющегося свойства
Структурные директивы
Структурные директивы не являются домочкой в том смысле, что они создают, уничтожают или повторно создают элементы DOM на основе определенных условий.
Это огромное значение от того, что скрытый
Директива атрибута делает. Это потому, что скрытый
Сохраняет элемент DOM, но скрывает его от пользователя, тогда как структурные директивы, такие как * NGIF
Уничтожить элементы.
* NGFOR
и [Ngswitch]
Также являются общими структурными директивами, и вы можете связать их к общим задачам расхода программирования.
Индивидуальные директивы атрибутов
У нас был быстрый взгляд на директивы и типы директив в угловых 2. И, как вы только что узнали, использование существующих директив очень просты. Давайте теперь будем немного глубже и создать некоторые, чтобы удовлетворить наши собственные потребности.
Angular 2 предоставляет чистые и простые API, чтобы помочь нам создавать пользовательские директивы. Вы окажетесь создавать пользовательские фиксаторы атрибутов, чем структурные директивы, поэтому давайте начнем с этого.
Давайте начнем
Настройка базового углового приложения, используя Угловой QuickStart или любой другой метод вашего выбора. QuickStart уже поставляется с простым приложение
Компонент, поэтому мы можем просто построить на это. То, что мы сделаем сейчас, состоит в том, чтобы создать общую папку в каталоге приложений, чтобы держать всех наших пользовательских директив, а затем экспортировать их, используя NGModule
Отказ
MyHidden: Исследование
Наша первая директива будет тематическим изучением существующих углов 2 скрытый
Директива. Давайте реализуем это, и это будет служить открывцом глаз о том, как эти вещи работают внутри:
// ./app/shared/hidden.directive.ts import { Directive, ElementRef, Renderer } from '@angular/core'; // Directive decorator @Directive({ selector: '[myHidden]' }) // Directive class export class HiddenDirective { constructor(el: ElementRef, renderer: Renderer) { // Use renderer to render the element with styles renderer.setElementStyle(el.nativeElement, 'display', 'none'); } }
Директивы такие же, как другие угловые 2 участника, созданные как класс. Затем класс украшен Директива
Декоратор, который импортируется из @ Угловая/ядра
бочонок
Директива определяет селектор, который будет выглядеть на наших взглядах. В этом случае [MyHidden]
Отказ
В классовом конструкторе мы используем 2 помощников DOM для отслеживания элемента хоста и представляют его стиль, настроив дисплей ни на что.
Нам нужно объявить и экспортировать эту директиву через SharedModule
Так что наш модуль приложения может загрузить и импортировать его. Тем самым делает его доступным для приложения, глобально.
// ./app/shared/shared.module.ts import { NgModule } from '@angular/core'; import { HiddenDirective } from './hidden.directive'; @NgModule({ declarations: [ HiddenDirective ], exports: [ HiddenDirective ] }) export class SharedModule{}
Теперь импортируйте в нашу AppModule
:
// ./app/app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; // Load SharedModule import { SharedModule } from './shared/shared.module'; import { AppComponent } from './app.component'; @NgModule({ // Import SharedModule imports: [BrowserModule, SharedModule], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule{}
На данный момент Директива доступна для нас для использования в любом месте нашего приложения. Давайте применим его где-то в шаблоне компонента приложений:
Welcome
Hidden Welcome
Мы добавляем директиву как атрибут ( myhidden
) на разметку
Вы можете увидеть, что один заголовок отображается, а другой скрытый. Скрытый не удален из дома, как показывает консоль. Угловое ядро скрытый
Директива может взять булеву, чтобы скрыть или не скрыть на основе стоимости.
Давайте расширим нашу работу так же:
// ./app/shared/hidden.directive.ts import { Directive, ElementRef, Input, Renderer } from '@angular/core'; @Directive({ selector: '[myHidden]' }) export class HiddenDirective { constructor(public el: ElementRef, public renderer: Renderer) {} @Input() myHidden: boolean; ngOnInit(){ // Use renderer to render the emelemt with styles console.log(this.myHidden) if(this.myHidden) { console.log('hide'); this.renderer.setElementStyle(this.el.nativeElement, 'display', 'none'); } } }
На этот раз мы используем Вход
Декоратор для получения значения образуют шаблон и передавать его к директиве. Мы должны перемещать реализацию от конструктора в Ngoninit
метод жизненного цикла, потому что MyHidden
Собственность будет установлена поздно. Ngoninit
будет ждать все процессы инициализации, чтобы быть завершены перед выполнением.
Атрибут теперь может быть добавлен в наш шаблон в качестве ввода, окруженного []
и логическое значение передано к нему:
Welcome
Hidden Welcome
валь
это недвижимость на нашем контроллере:
// ./app/app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html' }) export class AppComponent{ val = true; }
Мы все еще получаем тот же результат, но на этот раз у нас есть возможность переключить директиву логическими.
Подчеркивание директивы
Создание существующей директивы является избыточным, но мы должны были создать MyHidden
Директива, чтобы увидеть, как скрытый
работает внутри. Теперь давайте создадим что-то на самом деле полезное.
Директива, которую мы создадим дальше, добавят и подчеркивают украшение на наш текст на мыше. Это означает, что мы посмотрим, как обрабатывать события в директивах.
// ./app/shared/underline.directive.ts import { Directive, HostListener, Renderer, ElementRef } from '@angular/core'; @Directive({ selector: '[myUnderline]' }) export class UnderlineDirective{ constructor( private renderer: Renderer, private el: ElementRef ){} // Event listeners for element hosting // the directive @HostListener('mouseenter') onMouseEnter() { this.hover(true); } @HostListener('mouseleave') onMouseLeave() { this.hover(false); } // Event method to be called on mouse enter and on mouse leave hover(shouldUnderline: boolean){ if(shouldUnderline){ // Mouse enter this.renderer.setElementStyle(this.el.nativeElement, 'text-decoration', 'underline'); } else { // Mouse leave this.renderer.setElementStyle(this.el.nativeElement, 'text-decoration', 'none'); } } }
В приведенном выше примере мы решили не выполнять какие-либо действия в конструкторе или методе жизненного цикла. Мы решили написать метод под названием Hover
который украшен слушателями хоста. Метод называется слушателями хоста, и слушатели хоста являются слушателями событий, прикрепленные к элементу, проведению директивы.
Хост-слушатели Слушатели событий прикреплены к любому элементу, что хосты (Директива размещена на) директиве.
Мы можем прикрепить директиву к нашему шаблону, как так:
// ./app/app.component.htmlHover to underline
Тогда обновите SharedModule
объявить и экспортировать директиву:
// ./app/shared/shared.module.ts import { NgModule } from '@angular/core'; import { HiddenDirective } from './hidden.directive'; // Import new directive import { UnderlineDirective } from './underline.directive'; @NgModule({ declarations: [ HiddenDirective, // Declare new directive UnderlineDirective ], exports: [ HiddenDirective, // Export new directive UnderlineDirective ] }) export class SharedModule{}
Пользовательская структурная директива
Структурные директивы, как мы уже обсудили, манипулируют домом. Такие манипуляции могут создавать (не показывать) и уничтожать (не скрывать) элементы DOM.
Myif: Cate Execution
Так же, как мы повторно создали существующую директиву атрибута ( hidden
) в угловых 2, давайте повторно создадим существующую структурный директива ( NGIF
), чтобы увидеть, как приготовлены структурные директивы:
// ./app/shared/if.directive.ts import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[myIf]' }) export class IfDirective { constructor( private templateRef: TemplateRef, private viewContainer: ViewContainerRef ) { } @Input() set myIf(shouldAdd: boolean) { if (shouldAdd) { // If condition is true add template to DOM this.viewContainer.createEmbeddedView(this.templateRef); } else { // Else remove template from DOM this.viewContainer.clear(); } } }
Самое важное различие с тем, как мы создали нашу директиву атрибута, заключается в том, как они предоставляются DOM. Директива атрибута использует Elementref
и Рендерер
к оказывать и повторно рендеринг Хотя структурные директивы используют Templateref
и ViewContainerRef
к Обновить содержание DOM.
Директива имеет входной установку, который получает логическое значение. Если логическое значение разрешится к true, мы используем ViewContainer
‘s createembeddedview
Метод для визуализации шаблона. Мы можем получить шаблон через Templateref
Отказ
Когда логический регистр решает ложно, мы очищаем ViewContainer
Отказ
Так называемый ViewContainer
В этом случае относится к структурной директиве.
Вы можете продолжить объявить и экспортировать директиву в SharedModule
:
// ./app/shared/shared.module.ts // Truncated for brevity import { IfDirective } from './if.directive'; @NgModule({ declarations: [ HiddenDirective, UnderlineDirective, // New directive IfDirective ], exports: [ HiddenDirective, UnderlineDirective, // New directive IfDirective ] }) export class SharedModule{}
Наш новый Если
Директирующее исследование теперь может быть применено в любом месте в приложении:
Inside if
Атрибут против структуры: когда использовать какой?
В тех случаях, когда вам необходимо выбрать либо директива атрибута, либо структурный директива, выбирая между двумя двумя, может быть запутано, и вы можете в конечном итоге с неправильным выбором только потому, что это, как будто это решает проблему – ное решение может быть ограничено определенная степень.
Один хороший пример находится во время ситуации о видимости, где вы застряли между выбором, следует ли использовать скрытый
Директива атрибута или NGIF
структурная директива.
Это простое правило может руководить вами, когда это произойдет – если элемент, который ходит директиву, все равно будет полезен в DOM, даже если он не виден, то это хорошая идея, чтобы скрыть его, чем его удалить. В противном случае элемент должен быть удален из DOM, потому что он более эффективен, чтобы сохранить и управлять меньшим количеством предметов на DOM.
Однако всегда есть небольшая цена. Скрытие будет держать вашу DOM Intact, и вам просто нужно переключаться. Но это может также сделать его более сложным и покинуть Дом грязным. Иногда это может даже прийти с проблемами производительности. Удаление является уборщиком, но может быть дорого, если элемент должен быть восстановлен в срок службы приложения. В этом случае вам решать применить это простое правило и сделать ваше решение на основе вашей структуры и поведения приложений.