Angular 中的 Attribute 綁定可幫助你直接設(shè)置 Attribute 值。使用 Attribute 綁定,你可以提升無(wú)障礙性、動(dòng)態(tài)設(shè)置應(yīng)用程序樣式以及同時(shí)管理多個(gè) CSS 類或樣式。
包含本指南中的代碼片段的可工作示例,請(qǐng)參閱現(xiàn)場(chǎng)演練 / 下載范例。
建議你盡可能設(shè)置帶有 Property 綁定的元素的 Property。但是,有時(shí)你沒有可綁定的元素 Property。在這種情況下,可以使用 Attribute 綁定。
例如,ARIA和SVG 只有 Attribute。 ARIA 和 SVG 都不對(duì)應(yīng)于元素的 Property,也不設(shè)置元素的 Property。在這些情況下,必須使用 Attribute 綁定,因?yàn)闆]有相應(yīng)的目標(biāo) Property。
Attribute 綁定語(yǔ)法類似于 Property 綁定,但不是直接在方括號(hào)之間放置元素的 Property,而是在 Attribute 名稱前面加上前綴 ?attr
?,后跟一個(gè)點(diǎn) ?.
?。然后,使用解析為字符串的表達(dá)式設(shè)置 Attribute 值。
<p [attr.attribute-you-are-targeting]="expression"></p>
當(dāng)表達(dá)式解析為 ?
null
?或 ?undefined
?時(shí),Angular 會(huì)完全刪除該 Attribute。
Attribute 綁定的主要用例之一是設(shè)置 ARIA Attribute,如下所示:
<!-- create and set an aria attribute for assistive technology -->
<button [attr.aria-label]="actionName">{{actionName}} with Aria</button>
Attribute 綁定的另一個(gè)常見用例是綁定到表格中的 ?colspan
?Attribute。?colspan
?Attribute 可幫助你以編程方式讓表格保持動(dòng)態(tài)。根據(jù)應(yīng)用中用來(lái)填充表的數(shù)據(jù)量,某一行要跨越的列數(shù)可能會(huì)發(fā)生變化。
要將 Attribute 綁定到 ?<td>
? 的 ?colspan
?Attribute:
colspan
?:?[attr.colspan]
? 。[attr.colspan]
? 設(shè)置為等于某個(gè)表達(dá)式。在下面的示例中,我們將 ?colspan
?Attribute 綁定到表達(dá)式 1 + 1。
<!-- expression calculates colspan=2 -->
<tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
此綁定會(huì)導(dǎo)致 ?<tr>
? 跨越兩列。
有時(shí),Property 名和 Attribute 名之間存在差異。
?colspan
?是 ?<tr>
? 的 Attribute,而 ?colSpan
?(注意 “S” 是大寫)是 Property。使用 Attribute 綁定時(shí),請(qǐng)使用帶小寫 “s” 的 ?colspan
?。
可以用類綁定從元素的 ?class
?Attribute 中添加和刪除 CSS 類名稱。
要?jiǎng)?chuàng)建單個(gè)類綁定,請(qǐng)使用前綴 ?class
?后跟一個(gè)點(diǎn)和 CSS 類的名稱,例如 ?[class.sale]="onSale"
?。?onSale
?為真值時(shí)添加類,在表達(dá)式為假值時(shí)(?undefined
?除外)刪除類。
要綁定到多個(gè)類,請(qǐng)使用 ?[class]
? 來(lái)設(shè)置表達(dá)式 - 例如,?[class]="classExpression"
?,此表達(dá)式可以取如下值:
對(duì)于對(duì)象格式,Angular 會(huì)在其關(guān)聯(lián)的值為真時(shí)才添加類。
對(duì)于任何類似對(duì)象的表達(dá)式(例如 ?
object
?、?Array
?、?Map
?或 ?Set
?,必須更改對(duì)象的引用,Angular 才能更新類列表。在不更改對(duì)象引用的情況下只更新其 Attribute 是不會(huì)生效的。
如果同一類名有多個(gè)綁定,Angular 會(huì)根據(jù)樣式優(yōu)先級(jí)來(lái)確定要使用的綁定。
下表是各種類綁定語(yǔ)法的小結(jié)。
綁定類型 |
語(yǔ)法 |
輸入類型 |
范例輸入值 |
---|---|---|---|
單一類綁定 |
[class.sale]="onSale"
|
boolean | undefined | null
|
true , false
|
多重類綁定 |
[class]="classExpression"
|
string
|
"my-class-1 my-class-2 my-class-3"
|
Record<string, boolean | undefined | null>
|
{foo: true, bar: false}
|
||
Array <string > |
['foo', 'bar']
|
可以用樣式綁定來(lái)動(dòng)態(tài)設(shè)置樣式。
要?jiǎng)?chuàng)建對(duì)單個(gè)樣式的綁定,請(qǐng)使用前綴 ?style
?后跟一個(gè)點(diǎn)和 CSS style Attribute 的名稱,例如 ?[style.width]="width"
?。 Angular 會(huì)將該 Attribute 設(shè)置為綁定表達(dá)式的值,這個(gè)值通常是一個(gè)字符串。(可選)你還可以添加單位擴(kuò)展,例如 ?em
?或 ?%
? ,它的值需要數(shù)字類型。
你可以用中線格式或 camelCase 格式編寫樣式 Attribute 名。
<nav [style.background-color]="expression"></nav> <nav [style.backgroundColor]="expression"></nav>
要切換多個(gè)樣式,請(qǐng)綁定到 ?[style]
? Attribute,例如 ?[style]="styleExpression"
? 。?styleExpression
?可以是如下格式之一:
"width: 100px; height: 100px; background-color: cornflowerblue;"
?。{width: '100px', height: '100px', backgroundColor: 'cornflowerblue'}
?。注意,不支持把數(shù)組綁定給 ?[style]
?。
當(dāng)把 ?
[style]
? 綁定到對(duì)象表達(dá)式時(shí),該對(duì)象的引用必須改變,這樣 Angular 才能更新這個(gè)類列表。在不改變對(duì)象引用的情況下更新其屬性值是不會(huì)生效的。
@Component({
selector: 'app-nav-bar',
template: `
<nav [style]='navStyle'>
<a [style.text-decoration]="activeLinkStyle">Home Page</a>
<a [style.text-decoration]="linkStyle">Login</a>
</nav>`
})
export class NavBarComponent {
navStyle = 'font-size: 1.2rem; color: cornflowerblue;';
linkStyle = 'underline';
activeLinkStyle = 'overline';
/* . . . */
}
如果同一個(gè)樣式 Attribute 有多個(gè)綁定,Angular 將使用樣式優(yōu)先級(jí)來(lái)確定要使用的綁定。
下表是各種樣式綁定語(yǔ)法的小結(jié)。
綁定類型 |
語(yǔ)法 |
輸入屬性 |
范例輸入值 |
---|---|---|---|
單一樣式綁定 |
[style.width]="width"
|
string | undefined | null
|
"100px"
|
帶單位的單一樣式綁定 |
[style.width.px]="width"
|
number | undefined | null
|
100
|
多重樣式綁定 |
[style]="styleExpression"
|
string
|
"width: 100px; height: 100px"
|
Record<string, string | undefined | null>
|
{width: '100px', height: '100px'}
|
?
NgStyle
?指令可以用作代替直接綁定 ?[style]
? 的方法。但是,最好使用上述不用 ?NgStyle
?的綁定語(yǔ)法,因?yàn)橛捎?nbsp;Angular 中樣式綁定的改進(jìn),?NgStyle
?不再提供顯著價(jià)值,將來(lái)可能會(huì)被刪除。
一個(gè) HTML 元素可以將其 CSS 類列表和樣式值綁定到多個(gè)源(例如,來(lái)自多個(gè)指令的宿主綁定)。
當(dāng)有多個(gè)到相同的類名或樣式屬性的綁定時(shí),Angular 使用一組優(yōu)先規(guī)則來(lái)解決沖突并確定最終將哪些類或樣式應(yīng)用于元素。
樣式優(yōu)先級(jí)(從高到低)
- 模板綁定
- 屬性綁定(例如,?
<div [class.foo]="hasFoo">
? 或 ?<div [style.color]="color">
? )- 映射表綁定(例如,?
<div [class]="classExpr">
? 或 ?<div [style]="styleExpr">
? )- 靜態(tài)值(例如 ?
<div class="foo">
? 或 ?<div style="color: blue">
? )- 指令宿主綁定
- 屬性綁定(例如,?
host: {'[class.foo]': 'hasFoo'}
? 或 ?host: {'[style.color]': 'color'}
? )- 映射表綁定(例如,?
host: {'[class]': 'classExpr'}
? 或 ?host: {'[style]': 'styleExpr'}
? )- 靜態(tài)值(例如,?
host: {'class': 'foo'}
? 或 ?host: {'style': 'color: blue'}
? )- 組件宿主綁定
- 屬性綁定(例如,?
host: {'[class.foo]': 'hasFoo'}
? 或 ?host: {'[style.color]': 'color'}
? )- 映射表綁定(例如,?
host: {'[class]': 'classExpr'}
? 或 ?host: {'[style]': 'styleExpr'}
? )- 靜態(tài)值(例如,?
host: {'class': 'foo'}
? 或 ?host: {'style': 'color: blue'}
? )
總之,類或樣式綁定越具體,其優(yōu)先級(jí)就越高。
綁定到具體類(例如 ?[class.foo]
? )將優(yōu)先于不特定 ?[class]
? 的綁定,并且綁定到特定樣式(例如 ?[style.bar]
? )將優(yōu)先于不特定 ?[style]
? 的綁定。
<h3>Basic specificity</h3>
<!-- The `class.special` binding overrides any value for the `special` class in `classExpression`. -->
<div [class.special]="isSpecial" [class]="classExpression">Some text.</div>
<!-- The `style.border` binding overrides any value for the `border` property in `styleExpression`. -->
<div [style.border]="border" [style]="styleExpression">Some text.</div>
當(dāng)涉及不同來(lái)源的綁定時(shí),也適用這些特異性規(guī)則。元素可能具有在其聲明的模板中的綁定、在其匹配的指令中的宿主綁定、在其匹配的組件中的宿主綁定。
模板綁定是最具體的,因?yàn)樗鼈儠?huì)直接且排他地應(yīng)用于元素,因此它們具有最高的優(yōu)先級(jí)。
指令宿主綁定被認(rèn)為不太具體,因?yàn)橹噶羁梢栽诙鄠€(gè)位置使用,因此它們的優(yōu)先級(jí)低于模板綁定。
指令通常會(huì)增強(qiáng)組件的行為,因此組件的宿主綁定具有最低的優(yōu)先級(jí)。
<h3>Source specificity</h3>
<!-- The `class.special` template binding overrides any host binding to the `special` class set by `dirWithClassBinding` or `comp-with-host-binding`.-->
<comp-with-host-binding [class.special]="isSpecial" dirWithClassBinding></comp-with-host-binding>
<!-- The `style.color` template binding overrides any host binding to the `color` property set by `dirWithStyleBinding` or `comp-with-host-binding`. -->
<div>
<comp-with-host-binding [style.color]="color" dirWithStyleBinding></comp-with-host-binding>
</div>
<h3>Dynamic vs static</h3>
<!-- If `classExpression` has a value for the `special` class, this value overrides the `class="special"` below -->
<div class="special" [class]="classExpression">Some text.</div>
<!-- If `styleExpression` has a value for the `border` property, this value overrides the `style="border: dotted darkblue 3px"` below -->
<div style="border: dotted darkblue 3px" [style]="styleExpression">Some text.</div>
<div class="readability">
<comp-with-host-binding dirWithHostBinding></comp-with-host-binding>
</div>
<app-my-input-with-attribute-decorator type="number"></app-my-input-with-attribute-decorator>
此外,綁定會(huì)優(yōu)先于靜態(tài)屬性。
在這里,?class
?和 ?[class]
? 具有相似的特異性,但是 ?[class]
? 綁定更優(yōu)先一些,因?yàn)樗莿?dòng)態(tài)的。
<h3>Dynamic vs static</h3>
<!-- If `classExpression` has a value for the `special` class, this value overrides the `class="special"` below -->
<div class="special" [class]="classExpression">Some text.</div>
<!-- If `styleExpression` has a value for the `border` property, this value overrides the `style="border: dotted darkblue 3px"` below -->
<div style="border: dotted darkblue 3px" [style]="styleExpression">Some text.</div>
可以用 ?undefined
?值來(lái)把高優(yōu)先級(jí)的樣式“委托”給較低優(yōu)先級(jí)的樣式。將樣式屬性設(shè)置為 ?null
?可以確保樣式被刪除,而將其設(shè)置為 ?undefined
?將導(dǎo)致 Angular 回退到該樣式的次高優(yōu)先級(jí)綁定。
例如,考慮以下模板:
<comp-with-host-binding dirWithHostBinding></comp-with-host-binding>
假設(shè) ?dirWithHostBinding
?指令和 ?comp-with-host-binding
? 組件都具有 ?[style.width]
? 宿主綁定。在這里,如果 ?dirWithHostBinding
?將其綁定設(shè)置為 ?undefined
?,則 ?width
?屬性將回退到 ?comp-with-host-binding
? 宿主綁定的值。但是,如果 ?dirWithHostBinding
?將其綁定設(shè)置為 ?null
?,則會(huì)完全刪除 ?width
?
在某些情況下,你需要根據(jù)在 host 元素上以 HTML 屬性的形式設(shè)置的靜態(tài)值來(lái)區(qū)分組件或指令的行為。例如,你可能有一個(gè)指令,需要知道 ?<button>
? 或 ?<input>
? 元素的 ?type
?值。
Attribute參數(shù)裝飾器非常適合通過依賴注入來(lái)將 HTML 屬性的值傳遞給組件/指令構(gòu)造函數(shù)。
這里注入的值將捕獲指定 HTML 屬性的當(dāng)前值。將來(lái)對(duì)屬性值的修改不會(huì)反映到注入的值中。
import { Attribute, Component } from '@angular/core';
@Component({
selector: 'app-my-input-with-attribute-decorator',
template: '<p>The type of the input is: {{ type }}</p>'
})
export class MyInputWithAttributeDecoratorComponent {
constructor(@Attribute('type') public type: string) { }
}
<app-my-input-with-attribute-decorator type="number"></app-my-input-with-attribute-decorator>
在前面的示例中,?app.component.html
?的結(jié)果為:The type of the input is: number。
另一個(gè)示例是RouterOutlet指令,該指令利用 Attribute 裝飾器檢索每個(gè)路由插座上的唯一名稱。
@ATTRIBUTE() VS @INPUT()
請(qǐng)記住,要持續(xù)跟蹤 Attribute 的值并更新關(guān)聯(lián)的 Property 時(shí),請(qǐng)使用 ?@Input()
?。若要將 HTML 屬性的值注入到組件或指令的構(gòu)造函數(shù)中,請(qǐng)使用?@Attribute()
?。
更多建議: