Angular可复用Form组件SecComponent提交后无法打印date值问题求助
Angular自定义复用表单控件值无法同步问题解决方案
SecComponent提交时无法获取date字段值的问题,是Angular自定义表单控件没有正确实现ControlValueAccessor相关配置导致的,遗漏配置和修复方案如下:
- 遗漏自定义表单控件注册配置
Angular表单模块无法自动识别自定义组件为表单控件,需要在组件@Component装饰器的providers数组中注册NG_VALUE_ACCESSOR令牌,将当前组件声明为表单值访问器:
import { Component, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-sec', templateUrl: './sec.component.html', styleUrls: ['./sec.component.css'], // 新增以下provider配置 providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SecComponent), multi: true } ] }) export class SecComponent implements ControlValueAccessor { // 后续实现ControlValueAccessor接口方法 }
- 遗漏ControlValueAccessor接口方法的完整实现
需要完整实现ControlValueAccessor的4个接口方法,完成内部组件值和外部表单的双向同步:
export class SecComponent implements ControlValueAccessor { // 内部存储date值 date: string = ''; // 存储值变化、touched状态的回调函数,由Angular表单模块自动传入 private onChange = (val: string) => {}; private onTouched = () => {}; isDisabled = false; // 外部表单更新值时会调用该方法,同步到内部date变量 writeValue(value: string): void { if (value !== undefined && value !== null) { this.date = value; } } // 注册值变化回调,内部值变化时需要调用该回调通知外部表单 registerOnChange(fn: (val: string) => void): void { this.onChange = fn; } // 注册touched状态回调,控件被交互时调用通知外部表单 registerOnTouched(fn: () => void): void { this.onTouched = fn; } // 可选:响应外部表单的禁用状态设置 setDisabledState(isDisabled: boolean): void { this.isDisabled = isDisabled; } // 绑定到模板中日期输入框的input/change事件 handleDateChange(event: Event): void { const input = event.target as HTMLInputElement; this.date = input.value; // 通知外部表单值更新 this.onChange(this.date); // 标记控件已被交互 this.onTouched(); } }
- 遗漏模板事件绑定
需要在组件模板的日期输入元素上绑定值变化事件到上面实现的handleDateChange方法:
<input type="text" [value]="date" [disabled]="isDisabled" (input)="handleDateChange($event)" placeholder="请选择日期" >
完成以上三处配置后,外部表单就可以正常获取到SecComponent中date字段的提交值。
内容的提问来源于stack exchange,提问作者MrRobot
相关产品推荐
相关产品推荐

