新建一个firstDirective.ts 文件 内容如下
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({'selector':[first]})
export class firstDirective{
constructor(el:ElementRef){
el.style.color = 'pink'
el.style.background = 'green'
}
}
上面我们定义了一个指令,如何调用呢
src/app/app.component.html
My First Attribute Directive
Highlight me!
src/app/app.component.ts
import { Component } from ‘@angular/core’;
@Component({
selector: ‘my-app’,
templateUrl: ‘./app.component.html’
})
export class AppComponent {
color: string;
}
这个时候我们已经把这个指令应用到了组件上,p标签背景色为绿色,文字是pink色。
结束了吗?没有,还有很重要的一步
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HighlightDirective } from './highlight.directive';
@NgModule({
imports: [ BrowserModule ],
declarations: [
AppComponent,
HighlightDirective
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
我么需要在模块的 declarations中引入他,这样在该模块下的组件都需要再重新引入了。
就这么简单吗,我们想尝试点难得
src/app/app.component.html
<h1>My First Attribute Directiveh1>
<h4>Pick a highlight colorh4>
<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>
<p [myHighlight]=“color” defaultColor=“violet”>
Highlight me too!
p>
我们把页面改成了这样,这是要干嘛,还有2个指令都加了中括号?
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
selector: ‘[myHighlight]’
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
//注意这2个位置的@input的写法
() defaultColor: string;
‘myHighlight’) highlightColor: string;
(‘mouseenter’)
onMouseEnter() {
this.highlight(this.highlightColor || this.defaultColor || ‘red’);
}
‘mouseleave’)
onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
从这里我们又发现了一个有趣的事情 p [myHighlight]="color">Highlight me! /p
指令居然也可以放在中括号里面,这样就可以作为父组件传递过来的值。
@HostListener('mouseenter') 监听组件mouseenter事件,当鼠标移上去的时候,点亮。
需要注意一点的是,如果子组件的属性名与父组件上一致时,@input()括号里面可以不写
接下来我们我们玩点花样,修改一下指令文件
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
selector: ‘div[myHighlight]’
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
() defaultColor: string;
‘myHighlight’) highlightColor: string;
(//我们在这里加了一个 [‘ e v e n t . t a r g e t ′ ] 这 个 必 须 加 不 然 b t n 找 不 到 < / s p a n > < s p a n c l a s s = " h l j s − m e t a " > @ H o s t L i s t e n e r < / s p a n > ( < s p a n c l a s s = " h l j s − s t r i n g " > ′ m o u s e e n t e r ′ < / s p a n > , [ < s p a n c l a s s = " h l j s − s t r i n g " > ′ event.target'] 这个必须加 不然btn找不到</span> <span class="hljs-meta">@HostListener</span>(<span class="hljs-string">'mouseenter'</span>, [<span class="hljs-string">' event.target′]这个必须加不然btn找不到</span><spanclass="hljs−meta">@HostListener</span>(<spanclass="hljs−string">′mouseenter′</span>,[<spanclass="hljs−string">′event.target’])
onMouseEnter(btn: HTMLElement) {
btn.style.color = ‘green’
this.highlight(this.highlightColor || this.defaultColor || ‘red’);
}
‘mouseleave’) onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
上面我们通过了btn来控制样式,所以有:
btn = this.el.nativeElement 指向的是当前指令的宿主。。。
@Directive({
selector: 'div[myHighlight]'
}) 这个意思是说 这个指令只能用在div标签上
我们再来看一个新鲜的
import { Directive, HostBinding, HostListener } from '@angular/core';
selector: ‘[exeButtonPress]’
})
export class ExeButtonPress {
(‘attr.role’) role = ‘button’;
(‘class.pressed’) isPressed: boolean;
@HostListener('mousedown') hasPressed() {
this.isPressed = true;
}
@HostListener('mouseup') hasReleased() {
this.isPressed = false;
}
}
我们又加入了一个新东西 HostBinding,这个东西又是干嘛的呢
1.@HostBinding('attr.role') role = 'button'; 所有的指令宿主元素都会有一个role属性,值为‘button’
2.@HostBinding('class.pressed') isPressed: boolean; 所有宿主元素在按下去的时候会有pressed类
我们来升级一个玩一下,控制dom的显示和隐藏
import {Directive, Input, TemplateRef, ViewContainerRef} from "@angular/core";
@Directive({
selector:'[myUnless]'
})
export class MyUnlessDirective{
//从宿主元素获取myUnless值 注入到newCondition
@Input('myUnless')
set condition(newCondition:boolean){
if(!newCondition){
this.viewContainer.createEmbeddedView(this.templateRef);
console.log(newCondition);
}else {
// 若boolValue为true 删除该宿主元素
this.viewContainer.clear();
console.log("clear");
}
}
constructor(
private templateRef:TemplateRef,
private viewContainer:ViewContainerRef
){}
}
/1
“boolValue”>
false
"!boolValue">
true
如果boolValue是false,那么第一个p就会在Dom中显示
接下来我就原创一个悬浮提示的指令
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: ‘div[tooltip]’
})
export class tooltipDirective {
constructor(private el: ElementRef) { }
@Input(‘myHighlight’) highlightColor: string;
//我们在这里加了一个 [‘ e v e n t . t a r g e t ′ ] 这 个 必 须 加 不 然 b t n 找 不 到 < / s p a n > @ H o s t L i s t e n e r ( < s p a n c l a s s = " h l j s − s t r i n g " > ′ m o u s e e n t e r ′ < / s p a n > , [ < s p a n c l a s s = " h l j s − s t r i n g " > ′ event.target'] 这个必须加 不然btn找不到</span> @HostListener(<span class="hljs-string">'mouseenter'</span>, [<span class="hljs-string">' event.target′]这个必须加不然btn找不到</span>@HostListener(<spanclass="hljs−string">′mouseenter′</span>,[<spanclass="hljs−string">′event.target’])
onMouseEnter(btn: HTMLElement) {
btn.style.color = ‘green’
let content = btn.getAttribute(‘content’)
let tooltip = document.createElement(‘div’)
tooltip.innerHTML = content
tooltip.style.position = ‘absolute’
//需要计算出离父元素左边的距离
let left = (parseInt(btn.style.left) - tooltip.offsetwidth)/2
tooltip.style.left = left + ‘px’
btn.appendChild(tooltip)
this.highlight(this.highlightColor || this.defaultColor || ‘red’);
}
@HostListener(‘mouseleave’) onMouseLeave() {
// 当从宿主元素离开时 直接删除该节点就是
this.el.nativeElement.removeChild(tooltip)
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
好了,今天指令就讲到这里,大家可以看下好好吸收,下回我会讲angular的路由和表单等。