Angular中的指令分为三种:
NgFor
和NgIf
。NgStyle
。接下来我们编写一个属性指令,当鼠标悬停在元素上时改变元素的背景色。
属性指令至少需要一个Directive
装饰器的控制类。Directive
装饰器指定指令的选择器,控制类实现指令的行为。
创建项目文件夹angular2-attribute-directives
,按照QuickStart构建环境。
在app
文件夹下创建文件highlight.directive.ts
:
import {Directive, ElementRef, Input} from 'angular2/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
我们从Angular库中引入了Directive
和ElementRef
。Directive
用于@Directive
装饰器,ElementRef
用于在指令的构造函数注入DOM元素的引用。暂时还不需要Input
,但是后面会用到。
ElementRef
是个能让我们直接访问DOM元素的服务,通过它的nativeElement
属性。
在AppComponent
中使用myHighlight
。修改app.component.html
:
<h1>My First Attribute Directive</h1>
<span myHighlight>Highlight me!</span>
修改app.component.ts
:
import {Component} from 'angular2/core';
import {HighlightDirective} from './highlight.directive';
@Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [HighlightDirective]
})
export class AppComponent { }
在浏览器中显示如下:
接下来改成鼠标移到元素上的时候改变背景色。
我们要做的是:检测鼠标移入和移出元素的事件;响应这些事件。
在指令的元数据中添加一个host
属性,在配置对象中指定鼠标事件和事件触发时调用的指令的方法。
host: {
'(mouseenter)': 'onMouseEnter()',
'(mouseleave)': 'onMouseLeave()'
}
host
属性指向的就是应用这个指令的DOM元素。在我们这个例子中就是<span>
。
我们也可以用JavaScript来为DOM元素(el.nativeElement
)添加事件监听。但是这样会有一些问题:在指令销毁时我们必须手动移除事件监听,而且我们需要直接使用DOM API,这是应该避免的。
接下来实现这两个事件处理器,并去掉构造函数中的内容,将注入的ElementRef
改成私有变量:
constructor(private el: ElementRef) { }
onMouseEnter() { this._highlight("yellow"); }
onMouseLeave() { this._highlight(null); }
private _highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
在浏览器中显示的效果如下:
目前颜色是直接硬编码在指令中。我们应该像这样能从外部进行设置:
<p [myHighlight]="color">Highlight me!</p>
我们需要为指令扩展一个highlightColor
输入属性。
export class HighlightDirective {
@Input('myHighlight') highlightColor: string;
private _defaultColor = 'red';
constructor(private el: ElementRef) { }
onMouseEnter() { this._highlight(this.highlightColor || this._defaultColor); }
onMouseLeave() { this._highlight(null); }
private _highlight(color:string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
更新AppComponent的模板:
<h1>My First Attribute Directive</h1>
<h4>Pick a highlight color</h4>
<div>
<input type="radio" name="colors" (click)="color='lightgreen'">Green
<input type="radio" name="colors" (click)="color='yellow'">Yellow
<input type="radio" name="colors" (click)="color='cyan'">Cyan
</div>
<p [myHighlight]="color">Highlight me!</p>
PS:注意到,我们并没有为AppComponent
添加color
属性。Angular会自动添加。但是在实际环境中最好还是手动添加上啦。
在浏览器中的效果如下:
我们再添加一个输入属性defaultColor
:
@Input() set defaultColor(colorName:string){
this._defaultColor = colorName || this._defaultColor;
}
defaultColor
属性有个setter用来覆盖默认的颜色,因此不需要getter。
我们如何绑定它呢?我们已经把myHighlight
属性名称作为绑定目标了。
记住,组件也是指令。我们可以为组件添加任意多的属性绑定。就像这样:
<my-component [a]="'a'" [b]="'b'" [c]="'c'"><my-component>
同样,我们可以对属性绑定这样做:
<p [myHighlight]="color" [defaultColor]="'violet'">
Highlight me too!
</p>
最后的效果如下:
完整代码
参考资料
Angular2官方文档