[從 0 開始的 Angular 生活]No.20 Angular 屬性型指令 (Attribute Directives)

前言

學完元件型指令後,接著介紹第二種 Angular 指令 - 屬性型指令 (Attribute Directives)

屬性型指令 (Attribute Directives)

這種 Directives 有個特性,就是本身不會有自己的 Template ,但是套用這個 Directives 的地方,會修改那一個元素或者是那一個標籤的外觀或者是行為。

在 Angular 內建的屬性型指令內有三種:

  • ngModule - 雙向繫結
  • ngStyle - 動態設置 CSS 的 Style
  • ngClass - 動態設置 CSS 的 className

透過第二與第三個 Directives 可以很容易地去修改現有 HTML 的外觀、 CSS 的 Style 、 或動態的套用一些 class 。

如何使用 ngStyle

現在我們替 HeaderComponent 內加入一個新功能,當點擊網站 LOGO 時,計算被點了幾下。

前置作業

  • 首先我們在 HeaderComponent 的 class 內做調整,加入 counter 屬性並補上點擊時 counter++ :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export class HeaderComponent implements OnInit {
title = 'firstAngular';
link = 'http://www.google.com';
imgUrl = '/assets/images/logo.png';
counter = 0;
constructor() { }

ngOnInit() {
}
changeTitle(altKey: boolean) {
if (altKey) {
this.title = 'changeTitle';
}
this.counter++;
}
}
  • 並且修改 HeaderComponent 的 Template 使用內嵌繫結
1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3>Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

搞定!運行開發伺服器確認功能是否正常運作

動態調整 h3 標籤內的字體大小

修改 HeaderComponent 的 Template

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [ngStyle]="{'font-size': (12 + counter) + 'px'}">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

這邊做了一個 ngStyle 的屬性繫結,但是 ngStyle 並不是 h3 標籤的 Property 也不是 Attribute 。

ngStyle 本身就是一個 Diretive ,這個 Diretive 可以透過 [] 繫結一個物件,然後這個物件的屬性就是要套用的 CSS 的 Style ,而值就是我們希望套用的值。

因此再次運行開發伺服器確認功能是否正常運作

這樣就有隨著點擊次數字體越來越大的感覺了!

進階用法

值得注意的是, ngStyle 後面跟著的是一個物件,這代表其實可以傳入多組 CSS 的 Style ,但是通通寫在 HTML 內會顯得很難看,所以我們也可以這麼處理:

class 內撰寫方法並回傳

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [ngStyle]="getStyle()">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export class HeaderComponent implements OnInit {
title = 'firstAngular';
link = 'http://www.google.com';
imgUrl = '/assets/images/logo.png';
counter = 0;
constructor() { }

ngOnInit() {
}
changeTitle(altKey: boolean) {
if (altKey) {
this.title = 'changeTitle';
}
this.counter++;
}
getStyle() {
return {'font-size': (12 + this.counter) + 'px'};
}
}

這麼處理的結果會跟剛才的結果一模一樣。

或者是直接透過屬性

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [ngStyle]="getStyle">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export class HeaderComponent implements OnInit {
title = 'firstAngular';
link = 'http://www.google.com';
imgUrl = '/assets/images/logo.png';
counter = 0;
getStyle = {
'font-size': 20 + 'px'
};
constructor() { }

ngOnInit() {
}
changeTitle(altKey: boolean) {
if (altKey) {
this.title = 'changeTitle';
}
this.counter++;
}
}

這麼做也是沒問題的!

ngStyle 的簡單用法

ngStyle 還有更簡單的使用方式,像是:

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [style.font-size]="(12+counter) + 'px'">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

直接在中括號內輸入 style 後面接上 . 直接加上想要套用的樣式即可,而等號後面則與剛才設定相同。

而如果你想要同時套用多種,可以這麼做:

1
2
3
4
5
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [style.font-size]="(12+counter) + 'px'"
[style.color]="'red'">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

而這個方法也可以使用 class 內的屬性或方法使其更易讀

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [style.font-size]="fontSize" [style.color]="fontColor">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export class HeaderComponent implements OnInit {
title = 'firstAngular';
link = 'http://www.google.com';
imgUrl = '/assets/images/logo.png';
counter = 0;
fontSize = 16 + 'px';
fontColor = 'red';
constructor() { }

ngOnInit() {
}
changeTitle(altKey: boolean) {
if (altKey) {
this.title = 'changeTitle';
}
this.counter++;
}
}

執行結果如下

這些方式可以選擇一種使用即可,看哪個順手就用哪個吧。

如何使用 ngClass

如果已經知道如何使用 ngStyle ,那麼 ngClass 肯定難不倒我們,兩者的用法幾乎是一樣的。

我們將剛才設定過 ngStyle 的地方全部刪除,並且加上 ngClass :

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [ngClass]="{cssClass: expression}">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

可以看到整體結構上基本同於 ngStyle ,等號後方一樣是接收一個物件,因此剛才介紹的簡化方法 (寫在 class 的屬性、方法內) 同樣適用於 ngClass 。

於是可以修改成這樣

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [ngClass]="{'highlight': counter % 2 == 0}">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

物件屬性就是要設定的 className , 而不同於 ngStyle 的是,這個地方的值要輸入布林值。

  • 當值為 True 時套用這個 className ,反之則不套用

接著新增 highlight 這個 className 吧

header.component.scss

1
2
3
.highlight{
background-color: red;
}

搞定,接著測試看看吧!

當 counter 除以 2 餘數等於 0 時套用 highlight

當 counter 除以 2 餘數不等於 0 時不套用 highlight

ngClass 的簡單用法

聰明如你,想必已經猜到了如何使用,不囉嗦直接看範例!

1
2
3
4
<div class="pull-left">
<h1><a [href]="link" id="title">{{title}}</a></h1>
<h3 [class.highlight]="counter % 2 == 0">Lorem ipsum dolor sit amet. {{counter}}</h3>
</div>

等號後方直接給布林值就可以了,這樣是不是更簡單了呢?

也就是說等號後方可以直接寫一個布林值、或者透過 class 內的屬性、方法回傳布林值,這些都是合法的。只要是 True 就套用這個 className ,反之則不套用。

小結

終於介紹完屬性型指令了,整理這些東西的時候不禁讓我回想起 Vue 裡面的 :class:style 這些東西,而新學會的這些東西也是相當的好記,語法本身也是蠻簡單的。

接下來就是 Angular 的第三種指令 - 結構型指令囉!

0%