Angularjs2 指令
在Angular1中,会经常使用到指令,主要作为一些功能组件的封装,通过module.directive(name, function){}
来创建一个指令,然后通过restrict
属性的ECMA
来约束指令的使用位置,所以我们可以将一些通用的模块功能,封装为一个指令,然后在开发中直接使用指令就可完成相关功能的导入,而在Angularjs2中,指令的这个目标当然还是保持一致的。
在Angularjs2中,指令主要分为三种类型:
- 组件 - 带有模板的指令(组件皆指令)
- 结构型指令 - 作用于DOM元素修改视图结构的指令(
NgIf
、NgFor
等) - 属性型指令 - 作用于DOM元素的外观和行为的指令(
NgStyle
等)
属性型指令
在前面基础语法中也提到过属性型指令,这里就依据教程简单的了解下自定义指令的写法,实现目标是:自定义实现一个可以修改元素内容以及样式的指令。
1 | import { Directive, ElementRef, Renderer2, AfterViewInit} from '@angular/core'; |
- 通过
Directive
注解来声明为指令,并配置指令元数据。 - 元数据中
selector
值为自定义的基于attribute的css选择器,用于通过元素的attribute来选择元素。 - 通过注入
ElementRef
可以获取到当前元素的引用,可以使用nativeElement。 - 通过注入
Renderer2
可以使用统一的接口对当前元素进行访问和操作。由于Angular提倡的是一套框架,多种平台,所以建议使用统一的接口访问。 - 实现生命周期中的
AfterViewInit
函数,可以是我们在指令初始化完成后完成一些操作。
我们在自定义指令中,通过Renderer2
对象的setProperty
和setStyle
接口来完成innerHTML
和style的color
设置。
然后将指令添加到的@NgModule
的declarations
中,然后在模板中使用指令:
1 | <div directiveDemo>Demo</div> |
运行结果将会看到一个红色的**Hi Directive!**出现在界面上。
结构型指令
结构型指令其实就是会修改HTML的布局,一般使用*****(星号)来标识。简单的实现一个结构型指令,且每个宿主上只能由一个结构型指令。这里使用官方的示例,类似NgIf
。
1 | import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; |
- 通过注入
TemplateRef
来获取<ng-template>
的内容。 - 通过注入
ViewContainerRef
来访问视图容器。
然后将指令添加到的@NgModule
的declarations
中,然后在模板中使用指令:
1 | <div *myUnless="true">Demo</div> |
运行结果后,可以通过修改myUnless
的值来看到效果。
到这里,关于自定义指令的初级介绍也就完成了,当然在自定义指令中必不可少的数据和事件交互,以及自定义指令中那些个自动注入的对象的作用等,我们会在后面一个一个的进行了解学习。
指令的自定义事件
在指令中,我们可以通过nativeElement
获取到原生元素,然后做各种操作,同时Angular2也提供了一个@HostListener
(位于@angular/core
包)来进行事件绑定,
1 | @HostListener('mouseenter') onMouseEnter(){ |
将上段代码加入到我们开头写的属性型指令中,然后运行,鼠标移动到红色的**Hi Directive!**上就可以看到事件被触发了。
结构型指令的内幕
在结构型指令中,在使用的时候都会提到*(星号)
,其实星号只是一个语法糖,经过Angular的处理最终都会编译成ng-template
,可以结合官方文档的实例来分析下*ngIf
的处理过程。
1 | <div *ngIf="true">Demo!</div> |
Angular会将*ngIf
先解析为一个template
属性,如下:
1 | <div template="ngIf true">Demo!</div> |
星号会被解析为一个template
属性,然后将ngIf
移动到属性值中。然后会继续解析template
属性为:
1 | <ng-template [ngIf] = "true"> |
ngIf
成为了ng-template
的一个属性,而宿主元素则成为了ng-template
的内容。而最终的展示效果为:
1 | <!--bindings={ |
<ng-template>
指令,是一个Angular元素,主要用来渲染HTML,只会以注释的方式来渲染。<ng-container>
指令,可以作为一个宿主元素使用,由于一个元素只能添加一个结构型指令,所以在一些需要多个结构型指令配合的情况下,如果使用HTML元素作为宿主元素,可能将会受到css样式的影响,这种情况下就推荐使用<ng-container>
元素,该元素并不会被添加到DOM中。
** 参考链接 **