Директивы (Angular directives)
Директивы используятся для манипуляций с DOM: удалить, добавить, изменить элемент или его свойства-атрибуты.
Angular 5 использует директивы, которые можно разделить на:
- Компоненты (Angular components)
- Структурные директивы (Angular structural directives)
- Директивы-атрибуты (Angular attribute directives)
- Встроенные директивы (Angular built in directives)
- Пользовательские директивы (Angular custom directives)
Компоненты (Angular components)
Тип директивы, который использует шаблон. Это наиболее часто используемый тип директив. Angular. Внутри такой директивы можно использовать другие директивы, типа: всроенные, пользовательские.
Создать компонент
ng generate component students
Angular CLI создаст в папке ./src/app файлы компонента:
- students.component.css
- students.component.html
- students.component.spec.ts
- students.component.ts
TypeScript код компонента - в файле: students.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-students',
templateUrl: './students.component.html',
styleUrls: ['./students.component.css']
})
export class StudentsComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
В файл app-modules.ts автоматически добавляются строки:
import { StudentsComponent } from './students/students.component';
и в секцию declaration:
declarations: [
...,
StudentsComponent
]
Структурные (Angular structural directives)
Позволяют менять структуру DOM, добавляя, удаляя, изменяя элементы.
Структурные директивы могут использоваться с HTML тегом <ng-template> или без него.
Существуют три встроенных структурных директивы: NgIf, NgFor и NgSwitch.
Структурные директивы - это тип директив, которыя изменяют структуру DOM.
Тег <ng-template> можно использовать, чтобы определить элемент, который мы хотим вставить в DOM.
Можно добавить имя директивы с помощью *, чтобы пропустить определение <ng-template> и использовать в качестве шаблона директивы элемент, к которому она привязана .
Изменим шаблон компонента:
<h2>
Компонент {{name}} работает
</h2>
<ng-template [ngIf]=" students.length > 0">
<h3>Список студентов:</h3>
</ng-template>
<ul>
<ng-template ngFor let-student [ngForOf]="students" ; let-i="index">
<li>Номер: {{i+1}} Имя:{{student[0]}} Курс:{{student[2]}}</li>
</ng-template>
</ul>
<hr>
<ul *ngFor="let student of students; even as i" [ngSwitch]="i">
<li style="background-color:gray" *ngSwitchCase="true">Четный:{{i}} Курс:{{student[2]}}</li>
<li style="background-color:lightGray" *ngSwitchCase="false">Четный:{{i}} Курс:{{student[2]}}</li>
<i *ngSwitchDefault>{{i}} Курс:{{student[2]}}</i>
</ul>
<hr>
Тег <ng-template>
<ng-template [ngIf]='condition'>
<p>I am the content to show</p>
</ng-template>
ngIf
<div *ngIf="condition">...</div>
<ng-template [ngIf]="condition"><div>...</div></ng-template>
<div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>...</ng-template>
<ng-template #elseBlock>...</ng-template>
<div *ngIf="condition as value; else elseBlock">{{value}}</div>
<ng-template #elseBlock>...</ng-template>
ngFor (ngForOf)
Синтаксис:
<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
<ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
<li>...</li>
</ng-template>
<ng-container *ngFor = " let item of items; let i = index"> <li [innerHTML] = 'item'>...</li> </ng-container>
Локальные переменные ngFor
- index: number: индекс текущего элемента в итерации
- first: boolean: ИСТИНА , если элемент - первый в итерации
- last: boolean: ИСТИНА , если элемент - последний в итерации
- even: boolean: ИСТИНА , если элемент имеет чётный индекс
- odd: boolean: ИСТИНА , если элемент имеет нечётный индекс
Пример:
<ul>Список студентов:
<ng-template ngFor let-student [ngForOf]="students" ; let-i="index">
<li>Номер: {{i+1}} Имя:{{student[0]}} Курс:{{student[2]}}</li>
</ng-template>
</ul>
NgSwitch
Используем в качестве переключателя внутреннюю переменную even цикла ngFor
<container-tag *ngFor="let student of students; even as i" [ngSwitch]="i">
<case1-tag style="background-color:gray" *ngSwitchCase="true">Четный:{{i}} Курс:{{student[2]}}</case1-tag>
<case2-tag style="background-color:lightGray" *ngSwitchCase="false">Четный:{{i}} Курс:{{student[2]}}</case2-tag>
<caseDefault-tag*ngSwitchDefault>{{i}} Курс:{{student[2]}}</caseDefault-tag>
</container-tag>
<ul *ngFor="let student of students; even as i" [ngSwitch]="i">
<li style="background-color:gray" *ngSwitchCase="true">Четный:{{i}} Курс:{{student[2]}}</li>
<li style="background-color:lightGray" *ngSwitchCase="false">Четный:{{i}} Курс:{{student[2]}}</li>
<i *ngSwitchDefault>{{i}} Курс:{{student[2]}}</i>
</ul>
Тег <ng-container>
<ng-container *ngIf="lessons">
<div class="lesson" *ngFor="let lesson of lessons">
<div class="lesson-detail">
{{lesson | json}}
</div>
</div>
</ng-container>
Директивы-свойства (Angular 5 attribute directives)
Позволяют менять внешний вид элементов посредством изменения их атрибутов.
Встроенные директивы (Angular built in directives)
Это, например, директивы:
- NgIf
- NgSwitch
- NgStyle
- NgClass
Пользовательские директивы (Angular custom derectives)
Создать директиву
ng create directive my-dir1
Простой пример1
Отредактировать TypeScript - my-dir1.directive.ts
import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[appMyDir1]'
})
export class MyDir1Directive {
constructor(myElement: ElementRef, myRenderer: Renderer2) {
myRenderer.setStyle(myElement.nativeElement, 'box-shadow', '2px 2px 12px #ccc');
myRenderer.setStyle(myElement.nativeElement, 'padding', '10px 20px');
}
}
Шаблон
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<hr>
<span></span>
<span appMyDir1>Test directive</span>
</div>
Класс ElementRef обеспечивает доступ к объектам DOM
Класс Renderer2
Класс Renderer2 представляет собой абстракцию, предоставляемую Angular в виде сервиса,
который позволяет управлять элементами приложения без непосредственного доступа к DOM. Это рекомендуемый подход,
потому что он упрощает разработку приложений, которые могут отображаться в средах, не имеющих доступа к DOM, например, на сервере, web-workers или на мобильном устройстве.
Renderer2 часто используется в пользовательских директивах из-за того, что Angular директивы используются для модификации элементов.
Этот пример В этом примере мы создаем новый div и создаем текстовый узел. Затем мы помещаем текстовый узел в наш новый div и,
наконец, наш div добавляется к элементу, на который ссылается наша директива:
constructor(private renderer: Renderer2, private el: ElementRef) {}
ngOnInit() {
const div = this.renderer.createElement('div');
const text = this.renderer.createText('Hello world!');
this.renderer.appendChild(div, text);
this.renderer.appendChild(this.el.nativeElement, div);
}