Angular 属性型指令会监听并修改其它 HTML 元素和组件的行为、Attribute 和 Property。 它们通常被应用在元素上,就好像它们是 HTML 属性一样,因此得名属性型指令。
许多 NgModule(例如 RouterModule 和 FormsModule 都定义了自己的属性型指令。最常见的属性型指令如下:
-
NgClass —— 添加和删除一组 CSS 类。
-
NgStyle —— 添加和删除一组 HTML 样式。
-
NgModel —— 将数据双向绑定添加到 HTML 表单元素。
1.NgClass
用 ngClass 同时添加或删除几个 CSS 类。
<some-element [ngClass]="'first second'">...</some-element>
<some-element [ngClass]="['first', 'second']">...</some-element>
<some-element [ngClass]="{
'first': true, 'second': true, 'third': false}">...</some-element>
<some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
<some-element [ngClass]="{
'class1 class2 class3' : true}">...</some-element>
要添加或删除单个类,请使用类绑定而不是 NgClass。
下面是在普通 HTML 中不用绑定来设置 class Attribute 的方法:
<!-- standard class attribute setting -->
<div class="foo bar">Some text</div>
你还可以使用类绑定来为一个元素添加和移除 CSS 类。
要创建单个类的绑定,请使用 class 前缀,紧跟一个点(.),再跟上 CSS 类名,比如[class.foo]="hasFoo"
。 当绑定表达式为真值的时候,Angular 就会加上这个类,为假值则会移除,但 undefined 是假值中的例外,参见样式委派 部分。
要想创建多个类的绑定,请使用通用的 [class] 形式来绑定类,而不要带点,比如 [class]="classExpr"
。 该表达式可以是空格分隔的类名字符串,或者用一个以类名为键、真假值表达式为值的对象。 当使用对象格式时,Angular 只会加上那些相关的值为真的类名。
2.NgStyle
使用 NgStyle 根据组件的状态同时动态设置多个内联样式。
<some-element [ngStyle]="{
'font-style': styleExp}">...</some-element>
<some-element [ngStyle]="{
'max-width.px': widthExp}">...</some-element>
<some-element [ngStyle]="objExp">...</some-element>
有些情况下,要考虑使用样式绑定来设置单个样式值,而不使用 NgStyle。
<!-- 不通过绑定在普通 HTML 中设置 style 属性 -->
<div style="font-size: smaller">Some text</div>
<!-- 通过绑定在普通 HTML 中设置 style 属性 -->
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">
This div is x-large or smaller.
</div>
NgStyle 指令可以作为 [style] 绑定的替代指令。但是,应该把上面这种[style]
样式绑定语法作为首选,因为随着 Angular 中样式绑定的改进,NgStyle 将不再提供重要的价值,并最终在未来的某个版本中删除。
样式的优先级规则
一个 HTML 元素可以把它的 CSS 类列表和样式值绑定到多个来源(例如,来自多个指令的宿主 host 绑定)。
当对同一个类名或样式属性存在多个绑定时,Angular 会使用一组优先级规则来解决冲突,并确定最终哪些类或样式会应用到该元素中。
某个类或样式绑定越具体,它的优先级就越高。
对具体类(例如[class.foo]
)的绑定优先于一般化的 [class]
绑定,对具体样式(例如 [style.bar]
)的绑定优先于一般化的[style]
绑定。
<h3>Basic specificity</h3>
<!-- The `class.special` binding will override any value for the `special`
class in `classExpr`. -->
<div [class.special]="isSpecial" [class]="classExpr">Some text.</div>
<!-- The `style.color` binding will override any value for the `color`
property in `styleExpr`. -->
<div [style.color]="color" [style]="styleExpr">Some text.</div>
3. [(ngModel)] :双向绑定
NgModel 指令允许你显示数据属性并在用户进行更改时更新该属性。这是一个例子:
<label for="example-ngModel">[(ngModel)]:</label>
<input [(ngModel)]="currentItem.name" id="example-ngModel">
导入 FormsModule
以使用 ngModel
要想在双向数据绑定中使用 ngModel 指令,必须先导入 FormsModule
并将其添加到 NgModule 的 imports 列表中。要了解关于 FormsModule 和 ngModel 的更多信息,参见表单一章。
记住,要导入 FormsModule 才能让 [(ngModel)] 可用,如下所示:
import {
FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular
/* . . . */
@NgModule({
/* . . . */
imports: [
BrowserModule,
FormsModule // <--- import into the NgModule
],
/* . . . */
})
export class AppModule {
}
通过分别绑定到 元素的 value 属性和 input 事件,可以达到同样的效果:
<label for="without">without NgModel:</label>
<input [value]="currentItem.name" (input)="currentItem.name=$event.target.value" id="without">
为了简化语法,ngModel 指令把技术细节隐藏在其输入属性 ngModel 和输出属性 ngModelChange 的后面:
<label for="example-change">(ngModelChange)="...name=$event":</label>
<input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">