在 Angular 中,ngModel 指令为我们提供了双向绑定的功能,使得表单控件的值和组件中的变量可以保持同步。本文将通过一个简单的示例来总结如何实现 ngModel 双向绑定。
什么是双向绑定?
双向绑定是指数据在视图(模板)和模型(组件)之间的双向流动。任何一方的改变都会立即反映到另一方。例如,当用户在表单输入框中输入内容时,组件的对应变量会自动更新,反之亦然。
组件实现
在组件中,我们需要定义一些属性和方法,以支持 ngModel 的双向绑定。以下是一个基本的实现示例:
import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
/**
* 自定义表单控件组件
*/
@Component({
selector: 'app-custom-input',
template: `
<div *ngFor="let option of options">
<input type="checkbox" [checked]="option.checked" (change)="checkedChange()" />
{{ option.value }}
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}
]
})
export class CustomInputComponent implements ControlValueAccessor {
/** 当前选中的值 */
value: any[] = [];
/** 保存 onChange 回调函数 */
onChange: (value: any[]) => void = () => {};
/** 保存 onTouch 回调函数 */
onTouch: () => void = () => {};
/** 控件选项示例 */
options = [
{ value: '选项1', checked: false },
{ value: '选项2', checked: false },
{ value: '选项3', checked: false }
];
/** 将新值写入组件 */
writeValue(value: any[]): void {
this.value = value;
this.options.forEach(option => {
option.checked = this.value.includes(option.value);
});
}
/** 注册当值更改时触发的回调函数 */
registerOnChange(fn: (value: any[]) => void): void {
this.onChange = fn;
}
/** 注册当控件被触摸时触发的回调函数 */
registerOnTouched(fn: () => void): void {
this.onTouch = fn;
}
/**
* 选中状态改变
*/
checkedChange(): void {
this.value = this.options.filter(item => item.checked).map(item => item.value);
// 更新数据
this.onChange(this.value);
this.onTouch();
}
}
关键方法解析
writeValue(value: any[]):此方法用于将外部值写入组件。当父组件更新值时,此方法会被调用。**registerOnChange(fn: (value: any[]) => void)**:此方法用于注册一个回调函数,该函数会在值变化时被调用。它允许父组件接收组件中的值变化。**registerOnTouched(fn: () => void)**:此方法用于注册一个回调函数,当控件被触摸时会调用此函数,通常用于标记控件为“脏”。**checkedChange()**:当选中状态发生变化时,更新当前选中的值,并调用onChange和onTouch回调。
在模板中使用
在父组件中使用自定义控件时,可以通过 ngModel 实现双向绑定,如下所示:
<app-custom-input [(ngModel)]="selectedValues"></app-custom-input>
在父组件中,selectedValues 变量将与自定义控件的选中值保持同步。
总结
通过自定义表单控件的实现,我们可以利用 Angular 的 ngModel 指令轻松实现双向数据绑定。这使得组件与表单控件之间的交互更加直观和高效。