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

双向绑定

Two-way binding

双向绑定为应用中的组件提供了一种共享数据的方式。使用双向绑定绑定来侦听事件并在父组件和子组件之间同步更新值。

Two-way binding gives components in your application a way to share data. Use two-way binding to listen for events and update values simultaneously between parent and child components.

包含本指南中的代码片段的可工作示例参见现场演练 / 下载范例

See the现场演练 / 下载范例for a working example containing the code snippets in this guide.

先决条件

Prerequisites

为了充分利用双向绑定,你应该对以下概念有基本的了解:

To get the most out of two-way binding, you should have a basic understanding of the following concepts:


双向绑定将属性绑定与事件绑定结合在一起:

Two-way binding combines property binding with event binding:

添加双向数据绑定

Adding two-way data binding

Angular 的双向绑定语法是方括号和圆括号的组合 [()][] 进行属性绑定,() 进行事件绑定,如下所示。

Angular's two-way binding syntax is a combination of square brackets and parentheses, [()]. The [()] syntax combines the brackets of property binding, [], with the parentheses of event binding, (), as follows.

src/app/app.component.html
      
      <app-sizer [(size)]="fontSizePx"></app-sizer>
    

双向绑定工作原理

How two-way binding works

为了使双向数据绑定有效,@Output() 属性的名字必须遵循 inputChange 模式,其中 input 是相应 @Input() 属性的名字。例如,如果 @Input() 属性为 size ,则 @Output() 属性必须为 sizeChange

For two-way data binding to work, the @Output() property must use the pattern, inputChange, where input is the name of the @Input() property. For example, if the @Input() property is size, the @Output() property must be sizeChange.

后面的 sizerComponent 具有值属性 size 和事件属性 sizeChangesize 属性是 @Input(),因此数据可以流入 sizerComponentsizeChange 事件是一个 @Output() ,它允许数据从 sizerComponent 流出到父组件。

The following sizerComponent has a size value property and a sizeChange event. The size property is an @Input(), so data can flow into the sizerComponent. The sizeChange event is an @Output(), which allows data to flow out of the sizerComponent to the parent component.

接下来,有两个方法, dec() 用于减小字体大小, inc() 用于增大字体大小。这两种方法使用 resize() 在最小/最大值的约束内更改 size 属性的值,并发出带有新 size 值的事件。

Next, there are two methods, dec() to decrease the font size and inc() to increase the font size. These two methods use resize() to change the value of the size property within min/max value constraints, and to emit an event that conveys the new size value.

src/app/sizer.component.ts
      
      export class SizerComponent {

  @Input()  size!: number | string;
  @Output() sizeChange = new EventEmitter<number>();

  dec() { this.resize(-1); }
  inc() { this.resize(+1); }

  resize(delta: number) {
    this.size = Math.min(40, Math.max(8, +this.size + delta));
    this.sizeChange.emit(this.size);
  }
}
    

sizerComponent 模板有两个按钮,分别将 click 事件绑定到 inc()dec() 方法。当用户单击按钮之一时, sizerComponent 调用相应的方法。 inc()dec() 这两个方法分别使用 +1-1 调用 resize() 方法,它使用新的 size 值引发 sizeChange 事件。

The sizerComponent template has two buttons that each bind the click event to the inc() and dec() methods. When the user clicks one of the buttons, the sizerComponent calls the corresponding method. Both methods, inc() and dec(), call the resize() method with a +1 or -1, which in turn raises the sizeChange event with the new size value.

src/app/sizer.component.html
      
      <div>
  <button (click)="dec()" title="smaller">-</button>
  <button (click)="inc()" title="bigger">+</button>
  <label [style.font-size.px]="size">FontSize: {{size}}px</label>
</div>
    

AppComponent 模板中, fontSizePx 被双向绑定到 SizerComponent

In the AppComponent template, fontSizePx is two-way bound to the SizerComponent.

src/app/app.component.html
      
      <app-sizer [(size)]="fontSizePx"></app-sizer>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>
    

AppComponent 中,通过将 fontSizePx 的值设置为 16 来设置初始 SizerComponent.size 值。

In the AppComponent, fontSizePx establishes the initial SizerComponent.size value by setting the value to 16.

src/app/app.component.ts
      
      fontSizePx = 16;
    

单击这些按钮将更新 AppComponent.fontSizePx。修改后的 AppComponent.fontSizePx 值将更新样式绑定,从而使显示的文本变大或变小。

Clicking the buttons updates the AppComponent.fontSizePx. The revised AppComponent.fontSizePx value updates the style binding, which makes the displayed text bigger or smaller.

双向绑定语法是属性绑定和事件绑定的组合的简写形式。拆成单独的属性绑定和事件绑定形式的 SizerComponent 代码如下:

The two-way binding syntax is shorthand for a combination of property binding and event binding. The SizerComponent binding as separate property binding and event binding is as follows.

src/app/app.component.html (expanded)
      
      <app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
    

$event 变量包含 SizerComponent.sizeChange 事件的数据。当用户单击按钮时,Angular 将 $event 赋值给 AppComponent.fontSizePx

The $event variable contains the data of the SizerComponent.sizeChange event. Angular assigns the $event value to the AppComponent.fontSizePx when the user clicks the buttons.

表单中的双向绑定
Two-way binding in forms

因为没有任何原生 HTML 元素遵循了 x 值和 xChange 事件的命名模式,所以与表单元素进行双向绑定需要使用 NgModel。关于如何在表单中使用双向绑定的更多信息,请参见 Angular NgModel

Because no native HTML element follows the x value and xChange event pattern, two-way binding with form elements requires NgModel. For more information on how to use two-way binding in forms, see Angular NgModel.