大纲
1、自定义指令之——属性指令
2、自定义属性指令的运行原理
3、自定义属性指令代码实践
4、自定义结构指令
5、自定义结构指令代码实践
自定义指令之——属性指令
在Angular2中,属性型指令的创建至少需要一个带有@Directive装饰器修饰的控制器类。@Directive装饰器指定了一个选择器名称,用于指出与此指令相关联的属性的名字。
Angular会为每一个被指令匹配上的元素创建一个该指令对应的控制器类的实例。并自动注入该控制器类依赖的别的类的实例。比如上面的代码中,Angualr会选择合适的时机,为我们注入 ElementRef 和 Renderer 的实例。
自定义属性指令的运行原理
Angular在编译模板时,检测到DOM元素上我们正在尝试绑定到某些属性 ,但Angualr并不能认识这些属性(非内置的属性指令)。Angular就会尝试在我们声明的 declarations 元数据数组中查找这个指令属性。 我们把 HighlightDirective 在元数据的 declarations 数组中进行了声明,这样一来 Angular 在发现这个指令的导入信息后,接着就会去检查对应的导入语句,从而找到 highlight.directive.ts 中导出的类,进而服务宿主元素对应的行为能力。
自定义属性指令代码实践
初级版——添加改变颜色
import { Directive, ElementRef, Renderer } from '@angular/core';
@Directive({
selector: '[prefixHighLight]'
})
export class HighlightDirective {
constructor(elem: ElementRef, renderer: Renderer) {
renderer.setElementStyle(elem.nativeElement, 'backgroundColor', 'red');
}
}
中级版——添加,当鼠标移动之后变色
import { Directive, ElementRef, Renderer, HostListener } from '@angular/core';
@Directive({
selector: '[prefixHighLight]'
})
export class HighlightDirective {
private _domElem: ElementRef;
private _renderer: Renderer;
constructor(elem: ElementRef, renderer: Renderer) {
this._domElem = elem.nativeElement;
this._renderer = renderer;
}
@HostListener('mouseenter')
onMouseEnter() {
this._renderer.setElementStyle(this._domElem, 'backgroundColor', 'red');
}
@HostListener('mouseleave')
onMouseLeave() {
this._renderer.setElementStyle(this._domElem, 'backgroundColor', null);
}
}
高级版本:自定义鼠标移动上去之后的颜色
import { Directive, ElementRef, Renderer, HostListener, Input } from '@angular/core';
@Directive({
selector: '[prefixHighLight]'
})
export class HighlightDirective {
//需要注意的是:这里的prefixHighLight不仅仅是指令的标识符,还是输入的绑定目标
@Input('prefixHighLight') highlightColor: string;
private _domElem: ElementRef;
private _renderer: Renderer;
private _defaultColor = 'red';
constructor(elem: ElementRef, renderer: Renderer) {
this._domElem = elem.nativeElement;
this._renderer = renderer;
}
@HostListener('mouseenter')
onMouseEnter() {
this._renderer.setElementStyle(this._domElem, 'backgroundColor', this.highlightColor || this._defaultColor);
}
@HostListener('mouseleave')
onMouseLeave() {
this._renderer.setElementStyle(this._domElem, 'backgroundColor', null);
}
}
自定义结构指令
自定义结构指令代码实践
/*
指令功能描述:该指令实现 ngIf 指令相反的效果,当指令的输入条件为 Falsy 值时,显示DOM元素。
ex:
<h1 *exeUnless="condition">Hello {{name}}</h1>
*/
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[exeUnless]'
})
export class UnlessDirective {
@Input('exeUnless')
set condition(newCondition: boolean) {
if (!newCondition) { // 创建模板对应的内嵌视图
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) {
}
}
代码网址
angular的实例教程中的angular-directive-custom