button
指令:
ng g directive button
對(duì)于指令,會(huì)生成兩個(gè)文件:
button.directive.ts
button.directive.spec.ts
// button.directive.ts
import { Directive } from '@angular/core';
@Directive({
selector: '[appButton]'
})
export class ButtonDirective {
constructor() { }
}
對(duì)于指令,selector
一般使用方括號(hào)屬性方式,如上。<button appButton>指令按鈕</button>
指令有兩種:屬性型指令
:修改宿主元素的樣式或行為等結(jié)構(gòu)型指令
,比如`*ngIf`,`*ngFor`:修改DOM結(jié)構(gòu)。button
指令還沒(méi)有什么作用,下面讓我們來(lái)修改一下,先往style.css
中添加下列樣式:
button.btn {
padding: 10px;
background: blue;
color: #fff;
border-radius: 4px;
border: none;
}
修改button.directive.ts
:
import { Directive, ElementRef, AfterViewInit, Renderer2 } from '@angular/core';
@Directive({
selector: '[appButton]'
})
export class ButtonDirective implements AfterViewInit{
constructor(private er: ElementRef, private renderer2: Renderer2) { }
ngAfterViewInit() {
this.renderer2.addClass(this.er.nativeElement, 'btn');
}
}
在上面的代碼中,我們將ElementRef
和Renderer2
注入構(gòu)造函數(shù),前者會(huì)得到添加了appButton
屬性的元素,后者是Angular提供的DOM API
操作。
注:ElementRef和Renderer2后續(xù)會(huì)詳解。
然后在demo-directive.component.html
中添加:
<button appButton>指令按鈕/button>
當(dāng)你打開網(wǎng)頁(yè)時(shí),會(huì)發(fā)現(xiàn)此button
添加上了btn樣式類(背景色變藍(lán),字體顏色變白色)。
當(dāng)然,還有一些快捷的方式來(lái)給使用了指令的宿主元素添加屬性和事件:
(1) @HostBinding()
再來(lái)修改一下button.directive.ts
:
export class ButtonDirective {
@HostBinding('style.font-size') fontSize = '20px';
...
}
當(dāng)你添加了上面的代碼時(shí),你會(huì)發(fā)現(xiàn)demo-directive.component.html
中的按鈕字體變大了。
注:@HostBinding()
里是的屬性和直接屬性綁定是一樣的效果,主要給宿主元素設(shè)置屬性。
(2) @HostListener
我們還可以為宿主元素綁定事件:
// button.directive.ts
@HostListener('click') onClick() {
alert('你點(diǎn)了我!');
}
添加如上代碼后,你可以試試點(diǎn)擊按鈕。
注:@HostListener()
里是事件名稱,后面跟著一個(gè)監(jiān)聽(tīng)函數(shù),名稱可以是任意合法的字符。
有些時(shí)候我們需要給這個(gè)指令傳遞一些值,如何實(shí)現(xiàn)呢?
還記得前面《組件通訊(@Input和@Output)》一章中我們講過(guò)@Input()
可以設(shè)置別名。
修改button.directive.ts
:
export class ButtonDirective implements AfterViewInit {
...
@Input('appButton') name: string; // 定義別名
constructor(private er: ElementRef, private renderer2: Renderer2) { }
ngAfterViewInit() {
...
if (this.name) {
const text = this.renderer2.createText(this.name);
this.renderer2.appendChild(this.er.nativeElement, text);
}
}
}
通過(guò)@Input()
定義與指令同名的輸入屬性,我們就可以給指令傳遞參數(shù)了:// demo-directive.component.html
<button appButton="額外名稱">指令按鈕</button>
結(jié)構(gòu)型指令
最常用的內(nèi)置結(jié)構(gòu)型指令有ngIf, ngFor, ngSwitch
。
(1) ngIf
在demo-directive.component.html
中添加:
<div>
<button (click)="isShow = !isShow">點(diǎn)擊試試</button>
<div *ngIf="isShow">ngIf結(jié)構(gòu)型指令</div>
</div>
隨著點(diǎn)擊按鈕,isShow
屬性值會(huì)在true和false之間切換,而div也會(huì)跟著顯示或隱藏,其實(shí)是插入或移除。
而在Angular4中,新增else
效果(使用模板變量#name):
<button (click)="isShowElse = !isShowElse">點(diǎn)擊試試ngIf else</button>
<div *ngIf="isShowElse else next">ngIf結(jié)構(gòu)型指令中的else</div>
<ng-template #next>else效果</ng-template>
有些時(shí)候我們還可以這樣:
<ng-container *ngIf="isShow"></ng-container>
ng-container
元素會(huì)將其里面的內(nèi)容插入或移除,但ng-container
元素不會(huì)出現(xiàn)在頁(yè)面里。
(2) ngFor
ngFor一般用來(lái)顯示數(shù)據(jù)列表:
// demo-directive.component.html
<li *ngFor="let book of books">{{book}}</li>
// demo-directive.component.ts
this.books = ['HTML', 'Javascript'];
帶索引:
<h4>帶索引</h4>
<ul>
<li *ngFor="let book of books; index as i">{{i + ':' + book}}</li>
</ul>
(3) ngSwitch
ngSwitch
與JavaScript中的switch類似:
<div [ngSwitch]="animal">
<div *ngSwitchCase="'dog'">汪</div>
<div *ngSwitchCase="'cat'">喵</div>
<div *ngSwitchDefault>哼</div>
</div>
自定義結(jié)構(gòu)型指令
我們可以創(chuàng)建自定義結(jié)構(gòu)型指令my-if.directive.ts
:
import { Directive, Input, ViewContainerRef, TemplateRef } from '@angular/core';
@Directive({
selector: '[appMyIf]'
})
export class MyIfDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set appMyIf(condition: boolean) {
if (condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
在上面的代碼中,我們使用@Input()
屬性裝飾器的setter
方法來(lái)定義appMyIf
方法,里面的condition
參數(shù)就是其屬性值。
使用demo-directive.component.html
:
<button (click)="isMyShow = !isMyShow">點(diǎn)擊試試</button>
<div *appMyIf="isMyShow">自定義結(jié)構(gòu)型指令appMyIf</div>
在上面的代碼中,當(dāng)isMyShow
變?yōu)閠rue時(shí),底部的內(nèi)容顯示出來(lái);當(dāng)為false時(shí),底部?jī)?nèi)容消失了。
如發(fā)現(xiàn)任何問(wèn)題或有好的建議,歡迎在下方評(píng)論留言。
更多建議: