Augular指令
通过添加和删除视图DOM元素来更改DOM布局 ----结构型指令
改变一个DOM元素的外观或行为 ----属性型指令
结构型指令
三个常用的内置结构型指令:NgIf、NgFor、NgSwitch
NgIf
<div *ngIf="模板表达式">123</div>
NgFor
<div *ngFor="let item of items">{{item.name}}</div>
“let item of items” 引号中的let item of items并不是模板表达式,而是Angular解释的一种小型语言
let item of items意思是将items数组中的每个条目存储到item中。并将其用于每次迭代的模板视图中
NgFor内置的变量
内置变量 | 描述 |
---|---|
item | item代表迭代的每个子项 |
index | 每个模板上下文的当前迭代的索引 |
last | 布尔值,指示当前项是否是迭代中的最后一项 |
even | 布尔值,指示当前索引是否是偶数索引 |
odd | 布尔值,指示当前索引是否是技术索引 |
NgSwitch
NgSwitch指令的用法与其它语言中switch case用法类似
NgSwitch NgSwitchCase NgSwitchDefault三个指令配合使用
ng-container
ng-container并不是一个指令,是Angular中的一个分组元素,可以简单理解为一个Angular提供的标签。
他不会影响样式或DOM布局,当没有合适的宿主元素时,用户可以使用ng-container对元素进行分组。
常见的使用场景是,当需要便利或者是if判断时,它可以起到一个载体的作用
属性型指令
三个常用的内置属性型指令:NgClass NgStyle NgContent
NgClass
利用该指令为元素动态的添加样式
支持三种不同的写法
- 使用空格分割的字符串
<div [ngClass]="css1 css2 css3">This div is initially saveable, unchanged, and special.</div>
- 字符串数组
<div [ngClass]="['css1','css2','css3']">This div is initially saveable, unchanged, and special.</div>
- 对象
<div [ngClass]="{'css1': true, 'css2': false, 'css3': true}">This div is initially saveable, unchanged, and special.</div>
当然也支持将这个对象定义在ts文件中,将NgClass指令绑定到该对象上,实现更多的动态操作
HTML自己提供的语法常见是
<div [class.css-name] = "true"></div>
相对于HTML提供的原生语法来说,NgClass指令的功能更加灵活
NgStyle
动态添加一组Style样式
用法:接收一个键值对的对象表达式
<div [ngStyle]="{font-size: 15px}">This div is initially saveable, unchanged, and special.</div>
NgContent
指令的格式是,可以理解为动态内容的占位符
一个简单例子
子组件 add-button
<button (click) = 'add()'> <ng-content></ng-content> </button>
父组件
<app-add-button> 添加明细 </app-add-button>
最后展示的是一个“添加明细”的按钮
NgContent在创建可重用组件时内容简化了不少,避免了绑定输入属性这些步骤,只需要设置好,在实际重用该组件的时候往其中嵌入我们需要的文本即可
可以将其理解成为一个进阶版的input
而且动态文本只是其应用的一部分,我们可以往其中放入包括HTML标签,甚至于其他的组件
使用@contentChildren()装饰器获取子组件列表
利用该指令操作通过ng-content投影进来的元素,类似于@ViewChild
注意子元素或指令的查询要在组件的AfterContentInit生命周期开始时才完成,所以需要在对应的生命周期函数中才能获取到要查询的元素
创建指令
@Directive常见的元数据配置选项
元数据配置选项 | 说明 |
---|---|
selector | 对应的是HTML标签的属性名称 |
inputs | 列举指令的一组可供数据绑定的输入属性 |
outputs | 列举指令的一组可供事件绑定的输出属性 |
host | 使用一组键值对,把类的属性映射到宿主元素的绑定属性和事件 |
指令将指定的行为附加到宿主元素上
所以Angular提供了两个操作宿主元素的对象
- ElementRef对象:通过该对象的nativeElement属性直接访问应用该指令的DOM元素
- Renderer2对象:通过该对象修改DOM元素的样式
this.renderer2.setStyle(this.elementRef.nativeElement, 'font-size', this.size);
除此之外还可以通过@HostBinding()装饰器绑定DOM属性
@HostBinding('style.background-color')
backgroundColor: string;
@HostBinding('textContent')
textContent: string = '创建指令';
创建属性型指令
利用@Input()属性将值传递给属性型指令
如果只需要一个输入属性,那么可以将输入属性的名字命名为与selector同名,这样在为指令传值的时候不用再去写所传入的属性名
当需要传入多个属性时,则需要在调用指令时指明输入的值是什么属性
@Directive({
selector: '[log]'
})
export class LogDirective implements OnInit{
@Input() log: string;
@Input() backgroundColor: string;
<button [log]="size" backgroundColor="red">创建指令</button>
还可以利用元数据配置项中的inputs项列举指令的一组可供数据绑定的输入属性,注意需要在属性中创建与inputs元数据中同名的属性接收值
@Directive({
selector: '[resize]',
inputs: ['size'],
host: {
'(click)': 'onClick($event)'
}
})
export class ResizeDirective implements OnInit {
size: string; //属性名需要与元数据中的输入属性相对应
利用元数据配置项中的host监听模板中元素的事件
@Directive({
selector: '[resize]',
inputs: ['size'],
host: {
'(click)': 'onClick($event)'
}
})
onClick(event: Event) {
this.count++;
this.textContent = '创建指令' + this.count;
}
创建结构型指令
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
/**
* Add the template content to the DOM unless the condition is true.
*/
@Directive({ selector: '[appUnless]'})
export class UnlessDirective {
private hasView = false;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set appUnless(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
结构指令简写形式
结构型指令(例如
*ngIf
)上的星号*
语法是 Angular 解释为较长形式的简写形式。 Angular 将结构型指令前面的星号转换为围绕宿主元素及其后代的<ng-template>
。下面是一个
*ngIf
的示例,如果hero
存在,则显示英雄的名称:<div *ngIf="hero" class="name">{{hero.name}}</div>
*ngIf
指令移到了<ng-template>
上,在这里它成为绑定在方括号[ngIf]
中的属性。<div>
的其余部分(包括其 class 属性)移到了<ng-template>
内部。<ng-template [ngIf]="hero"> <div class="name">{{hero.name}}</div> </ng-template>