Angular自定义表单控件:能否在writeValue中获取emitEvent值?
能否在自定义表单控件的writeValue方法中获取emitEvent参数?
答案是不行,默认情况下ControlValueAccessor接口定义的writeValue方法只接收value这一个参数,Angular表单体系在调用这个方法时,并不会把setValue里的emitEvent这类配置参数传递过来。
原因
setValue的配置选项(比如emitEvent)是Angular内部FormControl逻辑的一部分,主要用来控制是否触发valueChanges这类事件;而writeValue的职责很单一——只是把外部传入的值同步到自定义控件的视图层,两者的设计职责是分离的,所以不会传递额外参数。
替代方案
如果你的业务逻辑确实需要根据emitEvent的取值做不同处理,可以试试这两种方法:
方法1:自定义FormControl扩展类
自己封装一个FormControl,在重写的setValue方法里,除了调用原生逻辑,还主动把emitEvent参数传递给自定义控件:
// 自定义FormControl类 export class CustomFormControl extends FormControl { override setValue(value: any, options?: AbstractControlOptions | { emitEvent?: boolean; }): void { super.setValue(value, options); // 假设自定义控件实例存在,调用自定义方法传递emitEvent if (this.customControlInstance) { this.customControlInstance.onSetValueWithOptions(options?.emitEvent ?? true); } } } // 自定义表单控件组件里新增方法 export class MyCustomFormControl implements ControlValueAccessor { // 保存父组件的CustomFormControl实例 @Input() set formControl(control: CustomFormControl) { control.customControlInstance = this; } // 自定义方法接收emitEvent参数 onSetValueWithOptions(emitEvent: boolean) { // 这里可以拿到emitEvent的值做处理 console.log('emitEvent:', emitEvent); } writeValue(value: string) { // 原writeValue逻辑 } // 其他ControlValueAccessor方法... }
方法2:通过输入属性传递
父组件调用setValue时,额外给自定义控件传一个输入属性标记状态:
// 自定义表单控件组件 export class MyCustomFormControl implements ControlValueAccessor { @Input() skipEvent = false; writeValue(value: string) { // 这里可以使用skipEvent的值做判断 if (!this.skipEvent) { // 需要触发事件的逻辑 } // 同步视图值的逻辑 } // 其他ControlValueAccessor方法... }
父组件模板和代码:
<app-my-custom-form-control #customCtrl [skipEvent]="skipEmit"></app-my-custom-form-control>
// 父组件调用setValue时设置标记 skipEmit = true; this.myCustomFormControl.setValue('a value', { emitEvent: false }); // 执行完后可以重置标记(根据业务需求) setTimeout(() => this.skipEmit = false);
内容的提问来源于stack exchange,提问作者Antediluvian
相关产品推荐
相关产品推荐

