持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天。点击查看活动详情
结合上篇组件之间的传值,数据双向绑定使用的场景也是比较多的,本篇文章介绍如何实现组件之间的数据双向绑定。
-
同时使用 @Input() 和 @Output() 实现数据双向绑定
-
双向绑定为应用中的组件提供了一种共享数据的方式。使用双向绑定绑定来侦听事件并在父组件和子组件之间同步更新值。
前提条件:
为了充分利用双向绑定,你应该对以下概念有基本的了解:
属性绑定:
-
要绑定到元素的属性,请将其放在方括号 [] 中,这会将此属性标识为目标属性。
-
要绑定到元素的属性 ,请将其括在方括号 [] 内,这会将此属性标为目标属性。目标属性就是你要对其进行赋值的 DOM 属性 。
-
要为 image 元素的目标属性(src)赋值,请键入以下代码:
<img alt="item" [src]="itemImageUrl">
事件绑定
要绑定到事件,你可以使用 Angular 事件绑定语法。此语法由等号左侧括号中的目标事件名称和右侧带引号的模板语句组成。
创建以下示例;目标事件名是 click,模板语句是 onSave()。
<button (click)="onSave()">Save</button>
输入和输出
-
Angular 中的一个常见模式就是在父组件和一个或多个子组件之间共享数据。可以用 @Input() 和 @Output() 来实现这个模式。
-
@Input() 和 @Output() 为子组件提供了一种与其父组件通信的方法。
-
@Input() 允许父组件更新子组件中的数据。
-
@Output() 允许子组件向父组件发送数据。
双向绑定将属性绑定与事件绑定结合在一起:
| 绑定 | 绑定 |
|---|---|
| 属性绑定 | 设置特定的元素属性。 |
| 事件绑定 | 侦听元素更改事件。 |
添加双向数据绑定
Angular 的双向绑定语法是方括号和圆括号的组合 [()]。[] 进行属性绑定,() 进行事件绑定,如下所示。
<sizer [(size)]="fontSizePx"></sizer>
双向绑定工作原理
为了使双向数据绑定有效,@Output() 属性的名字必须遵循 inputChange 模式,其中 input 是相应 @Input() 属性的名字。比如,如果 @Input() 属性为 size,则 @Output() 属性必须为 sizeChange。
后面的 sizerComponent 具有值属性 size 和事件属性 sizeChange。size 属性是 @Input(),因此数据可以流入 ``sizerComponent。sizeChange事件是一个@Output()`,它允许数据从 sizerComponent 流出到父组件。
接下来,有两个方法,dec() 用于减小字体大小,inc() 用于增大字体大小。这两种方法使用 resize() 在最小/最大值的约束内更改 size 属性的值,并发出带有新 size 值的事件。
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'sizer',
templateUrl: './sizer.component.html',
styleUrls: ['./sizer.component.less']
})
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 事件。
<div>
<button type="button" (click)="dec()">-</button>
<button type="button" (click)="inc()">+</button>
<span>number:{{ size }}</span>
</div>
调用方式
<div>
<sizer [(size)]="count"></sizer>
<br />
<label>Number: <input type="number" [(ngModel)]="count" /></label>
</div>
<br />
<div>
<sizer [size]="count" (sizeChange)="count = $event"></sizer>
</div>
在 AppComponent 中,通过将 count 的值设置为 16 来设置初始 SizerComponent.size 值。
count = 16;