指令的类型
- 结构性指令:通过操作DOM(添加或移除),改变DOM的布局;如*ngIf, *ngFor, *ngSwitch等
- 属性型指令:改变元素、组件或其他指令的外观和行为;如ngClass, ngStyle, ngModel等
- 组件:是一种拥有模板的特殊指令。
关于结构型指令
结构型指令能够调整DOM结构,其依赖于一个宿主元素,能够对其宿主元素和子元素执行一些操作,需要注意,每个宿主元素上只能有一种结构型指令。
-
结构型指令以*开头,可以将 *理解为一种语法糖,Angular识别到 *会生成一组标签,包含其宿主元素及子元素。
以*ngIf为例:
<div *ngIf='true'>*ngIf Directive</div>angular会将其解析为:
<ng-template [ngIf]='true'> <div>ngIf Directive in ng-template</div> </ng-template>对比上述两者渲染出的DOM结构,两者没有任何区别:
-
关于
<ng-template>标签是Angular提供的一个标签,用来渲染HTML,但是它永远不会显示出来,它必须配合结构型指令一起使用,若单独使用,其内部的元素并不会显示,如下,div并不会渲染到DOM中:
<ng-template> <div>该内容并不会显示</div> </ng-template> -
关于
<ng-container>标签也是Angular提供的一组标签,利用该标签,可以将某些元素进行组合,但并不会影响样式及布局;与标签一样,Angular不会将其放进DOM中。以同时*ngFor+ *ngIf为例:
<div *ngFor="let item of [{name: 'a'}, {name: 'b'}, { name: null}]"> <span *ngIf='item.name'>{{item.name}}</span> </div>因为每个组主元素最多只能使用一个结构型指令,上例中使用了两层结构,渲染出来的结构同样为两层,显示如下:
若使用替代div,只会渲染一层的span标签,如下:
<ng-container *ngFor="let item of [{name: 'a'}, {name: 'b'}, { name: null}]"> <span *ngIf='item.name'>{{item.name}}</span> </ng-container>
因此,可以通过合理使用优化DOM结构。
-
自定义结构型指令
除了Angular提供的结构性指令外,也可以自定义结构型指令。同样,使用自定义指令时,angular会在宿主元素外层添加标签,可以使用TemplateRef获取标签中的内容,也可以通过ViewContainerRef访问视图容器,待以后再写一篇详细说明。
关于属性型指令
属性型指令会监听或修改其他元素或组建的行为,属性等,通常会作为属性名应用到元素上,如ngClass为元素添加class,ngStyle为元素添加样式,ngModel为表单元素添加绑定的对象等。
除了Angular提供的属性型指令外,也可以自定义。
在自定义属性型指令时,可以通过elementRef获取宿主元素的引用,通过nativeElement为宿主元素添加样式或class,通过@HostListener添加对宿主元素的事件监听。