Angular自定义指令

Angular自定义指令

我是上帝可爱多 关注
2017.07.20 15:18* 字数 560 阅读 420 评论 0
新建一个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';

@Directive({
selector: ‘[myHighlight]’
})
export class HighlightDirective {

constructor(private el: ElementRef) { }
//注意这2个位置的@input的写法
@Input() defaultColor: string;

@Input(‘myHighlight’) highlightColor: string;

@HostListener(‘mouseenter’)
onMouseEnter() {
this.highlight(this.highlightColor || this.defaultColor || ‘red’);
}

@HostListener(‘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';

@Directive({
selector: ‘div[myHighlight]’
})
export class HighlightDirective {

constructor(private el: ElementRef) { }

@Input() defaultColor: string;

@Input(‘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="hljsmeta">@HostListener</span>(<spanclass="hljsstring">mouseenter</span>,[<spanclass="hljsstring">event.target’])
onMouseEnter(btn: HTMLElement) {
btn.style.color = ‘green’
this.highlight(this.highlightColor || this.defaultColor || ‘red’);
}

@HostListener(‘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';

@Directive({
selector: ‘[exeButtonPress]’
})
export class ExeButtonPress {
@HostBinding(‘attr.role’) role = ‘button’;
@HostBinding(‘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


//2

"!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="hljsstring">mouseenter</span>,[<spanclass="hljsstring">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的路由和表单等。

你可能感兴趣的:(Angular,学习总结)