属性绑定
Property binding
Angular 中的属性绑定可帮助你设置 HTML 元素或指令的属性值。使用属性绑定,你可以执行诸如切换按钮、以编程方式设置路径,以及在组件之间共享值之类的功能。
Property binding in Angular helps you set values for properties of HTML elements or directives. With property binding, you can do things such as toggle button functionality, set paths programmatically, and share values between components.
包含本指南中的代码片段的工作示例,请参阅
See the
先决条件
Prerequisites
为了充分理解属性绑定,你应该熟悉以下内容:
To get the most out of property binding, you should be familiar with the following:
了解数据流
Understanding the flow of data
属性绑定在单一方向上将值从组件的属性送到目标元素的属性。
Property binding moves a value in one direction, from a component's property into a target element property.
有关侦听事件的更多信息,请参阅事件绑定。
For more information on listening for events, see Event binding.
要读取目标元素的属性或调用其方法,请参阅 ViewChild 和 ContentChild 的 API 参考手册。
To read a target element property or call one of its methods, see the API reference for ViewChild and ContentChild.
绑定到属性
Binding to a property
要绑定到元素的属性,请将其括在方括号 []
内,该括号会将属性标为目标属性。目标属性就是你要对其进行赋值的 DOM 属性。例如,以下代码中的目标属性是 img 元素的 src
属性。
To bind to an element's property, enclose it in square brackets, []
, which identifies the property as a target property. A target property is the DOM property to which you want to assign a value. For example, the target property in the following code is the image element's src
property.
<img [src]="itemImageUrl">
在大多数情况下,目标的名称就是 Property 的名称,哪怕它看起来像 Attribute 的名称。在这个例子中,src
就是 <img>
元素的 Property 名称。
In most cases, the target name is the name of a property, even when it appears to be the name of an attribute. In this example, src
is the name of the <img>
element property.
方括号 []
使 Angular 将等号的右侧看作动态表达式进行求值。如果不使用方括号,Angular 就会将右侧视为字符串字面量并将此属性设置为该静态值。
The brackets, []
, cause Angular to evaluate the right-hand side of the assignment as a dynamic expression. Without the brackets, Angular treats the right-hand side as a string literal and sets the property to that static value.
<app-item-detail childItem="parentItem"></app-item-detail>
省略方括号就会渲染出字符串 parentItem
,而不是 parentItem
的值。
Omitting the brackets renders the string parentItem
, not the value of parentItem
.
将元素的属性设置为组件属性的值
Setting an element property to a component property value
要将 <img>
的 src
属性绑定到组件的属性,请将目标 src
放在方括号中,后跟等号,然后是组件的属性。在这里组件的属性是 itemImageUrl
。
To bind the src
property of an <img>
element to a component's property, place the target, src
, in square brackets followed by an equal sign and then the property. The property here is itemImageUrl
.
<img [src]="itemImageUrl">
在组件类 AppComponent
中声明 itemImageUrl
属性。
Declare the itemImageUrl
property in the class, in this case AppComponent
.
itemImageUrl = '../assets/phone.png';
colspan
和 colSpan
colspan
and colSpan
最容易混淆的地方是 colspan
这个 Attribute 和 colSpan
这个 Property。请注意,这两个名称只有一个字母的大小写不同。
A common point of confusion is between the attribute, colspan
, and the property, colSpan
. Notice that these two names differ by only a single letter.
如果你这样写:
If you wrote something like this:
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
你会收到此错误:
You'd get this error:
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
如消息中所示,<td>
元素没有 colspan
Property。这是正确的,因为 colspan
是一个 Attribute — colSpan
(带大写 S
)才是相应的 Property。插值和 Property 绑定只能设置 Property,不能设置 Attribute。
As the message says, the <td>
element does not have a colspan
property. This is true because colspan
is an attribute—colSpan
, with a capital S
, is the corresponding property. Interpolation and property binding can set only properties, not attributes.
相反,你应该使用 Property 绑定并将其编写为:
Instead, you'd use property binding and write it like this:
<!-- Notice the colSpan property is camel case -->
<tr><td [colSpan]="1 + 1">Three-Four</td></tr>
另一个示例是在组件说它自己 isUnchanged
时禁用按钮:
Another example is disabling a button when the component says that it isUnchanged
:
<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Disabled Button</button>
另一个是设置指令的属性:
Another is setting a property of a directive:
<p [ngClass]="classes">[ngClass] binding to the classes property making this blue</p>
还有一个是设置自定义组件的模型属性,这是父组件和子组件进行通信的一种好办法:
Yet another is setting the model property of a custom component—a great way for parent and child components to communicate:
<app-item-detail [childItem]="parentItem"></app-item-detail>
切换按钮功能
Toggling button functionality
若要根据布尔值禁用按钮的功能,请将 DOM 的 disabled
Property 设置为类中的源属性(可能为 true
或 false
)。
To disable a button's functionality depending on a Boolean value, bind the DOM disabled
property to a property in the class that is true
or false
.
<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Disabled Button</button>
由于 AppComponent
中属性 isUnchanged
的值是 true
,Angular 会禁用该按钮。
Because the value of the property isUnchanged
is true
in the AppComponent
, Angular disables the button.
isUnchanged = true;
设置指令的属性
Setting a directive property
要设置指令的属性,请将指令放在方括号中,例如 [ngClass]
,后跟等号和一个源属性。在这里,这个源属性的值是 classes
。
To set a property of a directive, place the directive within square brackets , such as [ngClass]
, followed by an equal sign and the property. Here, the property is classes
.
<p [ngClass]="classes">[ngClass] binding to the classes property making this blue</p>
要使用该属性,必须在组件类中声明它,在这里是 AppComponent
。其 classes
的值是 special
。
To use the property, you must declare it in the class, which in this example is AppComponent
. The value of classes
is special
.
classes = 'special';
Angular 会将 special
类应用到 <p>
元素,以便你可以通过 special
来应用 CSS 样式。
Angular applies the class special
to the <p>
element so that you can use special
to apply CSS styles.
在组件之间绑定值
Bind values between components
要设置自定义组件的模型属性,请将目标属性(此处为 childItem
)放在方括号 []
中,其后跟着等号与源属性。在这里,这个源属性是 parentItem
。
To set the model property of a custom component, place the target, here childItem
, between square brackets []
followed by an equal sign and the property. Here, the property is parentItem
.
<app-item-detail [childItem]="parentItem"></app-item-detail>
要使用目标和源属性,必须在它们各自的类中声明它们。
To use the target and the property, you must declare them in their respective classes.
在组件类(这里是 ItemDetailComponent
)中声明 childItem
的目标。
Declare the target of childItem
in its component class, in this case ItemDetailComponent
.
例如,以下代码在其组件类(这里是 ItemDetailComponent
)中声明了 childItem
的目标。
For example, the following code declares the target of childItem
in its component class, in this case ItemDetailComponent
.
然后,代码包含一个带有 @Input()
装饰器的 childItem
属性,这样才能让数据流入其中。
Then, the code contains an @Input()
decorator with the childItem
property so data can flow into it.
@Input() childItem: string;
接下来,代码在其组件类(这里是 AppComponent
)中声明属性 parentItem
。在这个例子中, childItem
的类型为 string
,因此 parentItem
也必须为字符串。在这里,parentItem
的字符串值为 lamp
。
Next, the code declares the property of parentItem
in its component class, in this case AppComponent
. In this example the type of childItem
is string
, so parentItem
needs to be a string. Here, parentItem
has the string value of lamp
.
parentItem = 'lamp';
这种配置方式下,<app-item-detail>
的视图使用来自 childItem
的值 lamp
。
With this configuration, the view of <app-item-detail>
uses the value of lamp
for childItem
.
属性绑定与安全性
Property binding and security
属性绑定可以帮助确保内容的安全。例如,考虑以下恶意内容。
Property binding can help keep content secure. For example, consider the following malicious content.
evilTitle = 'Template <script>alert("evil never sleeps")</script> Syntax';
组件模板对内容进行插值,如下所示:
The component template interpolates the content as follows:
<p><span>"{{evilTitle}}" is the <i>interpolated</i> evil title.</span></p>
浏览器不会处理 HTML,而是原样显示它,如下所示。
The browser doesn't process the HTML and instead displays it raw, as follows.
"Template <script>alert("evil never sleeps")</script> Syntax" is the interpolated evil title.
Angular 不允许带有 <script>
标记的 HTML,既不能用于插值也不能用于属性绑定,这样就会阻止运行 JavaScript。
Angular does not allow HTML with <script>
tags, neither with interpolation nor property binding, which prevents the JavaScript from running.
但是,在以下示例中,Angular 在显示值之前会先对它们进行无害化处理。
In the following example, however, Angular sanitizes the values before displaying them.
<!--
Angular generates a warning for the following line as it sanitizes them
WARNING: sanitizing HTML stripped some content (see https://g.co/ng/security#xss).
-->
<p>"<span [innerHTML]="evilTitle"></span>" is the <i>property bound</i> evil title.</p>
插值处理 <script>
标记的方式与属性绑定的方式不同,但这两种方法都可以使内容无害。以下是经过无害化处理的 evilTitle
示例的浏览器输出。
Interpolation handles the <script>
tags differently than property binding, but both approaches render the content harmlessly. The following is the browser output of the sanitized evilTitle
example.
"Template Syntax" is the property bound evil title.
属性绑定和插值
Property binding and interpolation
通常,插值和属性绑定可以达到相同的结果。以下绑定会做相同的事。
Often interpolation and property binding can achieve the same results. The following binding pairs do the same thing.
<p><img src="{{itemImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="itemImageUrl"> is the <i>property bound</i> image.</p>
<p><span>"{{interpolationTitle}}" is the <i>interpolated</i> title.</span></p>
<p>"<span [innerHTML]="propertyTitle"></span>" is the <i>property bound</i> title.</p>
将数据值渲染为字符串时,可以使用任一种形式,只是插值形式更易读。但是,要将元素属性设置为非字符串数据值时,必须使用属性绑定。
You can use either form when rendering data values as strings, though interpolation is preferable for readability. However, when setting an element property to a non-string data value, you must use property binding.