button
指令:
ng g directive button
對于指令,會生成兩個文件:
button.directive.ts
button.directive.spec.ts
// button.directive.ts
import { Directive } from '@angular/core';
@Directive({
selector: '[appButton]'
})
export class ButtonDirective {
constructor() { }
}
對于指令,selector
一般使用方括號屬性方式,如上。<button appButton>指令按鈕</button>
指令有兩種:屬性型指令
:修改宿主元素的樣式或行為等結(jié)構(gòu)型指令
,比如`*ngIf`,`*ngFor`:修改DOM結(jié)構(gòu)。button
指令還沒有什么作用,下面讓我們來修改一下,先往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ù),前者會得到添加了appButton
屬性的元素,后者是Angular提供的DOM API
操作。
注:ElementRef和Renderer2后續(xù)會詳解。
然后在demo-directive.component.html
中添加:
<button appButton>指令按鈕/button>
當你打開網(wǎng)頁時,會發(fā)現(xiàn)此button
添加上了btn樣式類(背景色變藍,字體顏色變白色)。
當然,還有一些快捷的方式來給使用了指令的宿主元素添加屬性和事件:
(1) @HostBinding()
再來修改一下button.directive.ts
:
export class ButtonDirective {
@HostBinding('style.font-size') fontSize = '20px';
...
}
當你添加了上面的代碼時,你會發(fā)現(xiàn)demo-directive.component.html
中的按鈕字體變大了。
注:@HostBinding()
里是的屬性和直接屬性綁定是一樣的效果,主要給宿主元素設置屬性。
(2) @HostListener
我們還可以為宿主元素綁定事件:
// button.directive.ts
@HostListener('click') onClick() {
alert('你點了我!');
}
添加如上代碼后,你可以試試點擊按鈕。
注:@HostListener()
里是事件名稱,后面跟著一個監(jiān)聽函數(shù),名稱可以是任意合法的字符。
有些時候我們需要給這個指令傳遞一些值,如何實現(xiàn)呢?
還記得前面《組件通訊(@Input和@Output)》一章中我們講過@Input()
可以設置別名。
修改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);
}
}
}
通過@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">點擊試試</button>
<div *ngIf="isShow">ngIf結(jié)構(gòu)型指令</div>
</div>
隨著點擊按鈕,isShow
屬性值會在true和false之間切換,而div也會跟著顯示或隱藏,其實是插入或移除。
而在Angular4中,新增else
效果(使用模板變量#name):
<button (click)="isShowElse = !isShowElse">點擊試試ngIf else</button>
<div *ngIf="isShowElse else next">ngIf結(jié)構(gòu)型指令中的else</div>
<ng-template #next>else效果</ng-template>
有些時候我們還可以這樣:
<ng-container *ngIf="isShow"></ng-container>
ng-container
元素會將其里面的內(nèi)容插入或移除,但ng-container
元素不會出現(xiàn)在頁面里。
(2) ngFor
ngFor一般用來顯示數(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
方法來定義appMyIf
方法,里面的condition
參數(shù)就是其屬性值。
使用demo-directive.component.html
:
<button (click)="isMyShow = !isMyShow">點擊試試</button>
<div *appMyIf="isMyShow">自定義結(jié)構(gòu)型指令appMyIf</div>
在上面的代碼中,當isMyShow
變?yōu)閠rue時,底部的內(nèi)容顯示出來;當為false時,底部內(nèi)容消失了。
如發(fā)現(xiàn)任何問題或有好的建議,歡迎在下方評論留言。
更多建議: