填写这份《一分钟调查》,帮我们(开发组)做得更好!去填写Home

属性绑定

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现场演练 / 下载范例for a working example containing the code snippets in this guide.

先决条件

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.

要读取目标元素的属性或调用其方法,请参阅 ViewChildContentChild 的 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">
src/app/app.component.html
      
      <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 the right-hand side as a string literal and sets the property to that static value.

<app-item-detail childItem="parentItem"></app-item-detail>
src/app.component.html
      
      <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">
src/app/app.component.html
      
      <img [src]="itemImageUrl">
    

在组件类 AppComponent 中声明 itemImageUrl 属性。

Declare the itemImageUrl property in the class, in this case AppComponent.

itemImageUrl = '../assets/phone.png';
src/app/app.component.ts
      
      itemImageUrl = '../assets/phone.png';
    

colspancolSpan

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>
      
      <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
      
      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>
src/app/app.component.html
      
      <!-- 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>
src/app/app.component.html
      
      <!-- 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>
src/app/app.component.html
      
      <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>
src/app/app.component.html
      
      <app-item-detail [childItem]="parentItem"></app-item-detail>
    

切换按钮功能

Toggling button functionality

若要根据布尔值禁用按钮的功能,请将 DOM 的 disabled Property 设置为类中的源属性(可能为 truefalse)。

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>
src/app/app.component.html
      
      <!-- 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;
src/app/app.component.ts
      
      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>
src/app/app.component.html
      
      <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';
src/app/app.component.ts
      
      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>
src/app/app.component.html
      
      <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;
src/app/item-detail/item-detail.component.ts
      
      @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';
src/app/app.component.ts
      
      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';
src/app/app.component.ts
      
      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>
src/app/app.component.html
      
      <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.
      
      "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>
src/app/app.component.html
      
      <!--
 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.
      
      "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>
src/app/app.component.html
      
      <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.


下一步是什么

What's next