Angular14问题:删除FormArray项后剩余项值被清空
问题原因
你的StylingInputComponent同时执行了两种冲突的表单逻辑:
一方面通过@Input()接收外部传入的FormGroup实例,直接操作父组件的表单结构;另一方面又实现了ControlValueAccessor接口,将自身注册为独立的表单控件。当删除FormArray项时,StylingForm.valueChanges触发并调用registerOnChange中的回调,Angular表单系统会误判组件值发生变化,进而触发反向的writeValue调用,而writeValue里的setValue操作会错误覆盖剩余表单组的值,最终导致数据清空。
解决方法
移除ControlValueAccessor相关实现即可,因为你的场景是直接操作外部传入的FormGroup,不需要将组件封装为独立表单控件。
修改后的styling-input.component.ts代码:
@Component({ selector: 'styling-input', templateUrl: './styling-input.component.html', styleUrls: ['./styling-input.component.css'] // 移除NG_VALUE_ACCESSOR的providers配置 }) export class StylingInputComponent { // 移除ControlValueAccessor接口实现 @Input() StylingForm!: FormGroup<StylingParams>; get MediaQueryList() { return this.StylingForm.get('mediaQueries') as FormArray<FormGroup<MediaQueryParams>>; } // 移除writeValue、registerOnChange、registerOnTouched三个方法 private createMediaQueryGroup(): FormGroup<MediaQueryParams> { return new FormGroup<MediaQueryParams>({ selectorParams: new FormGroup<MediaSelectorParams>({ mediaType: new FormControl<MediaTypeParams>('all'), expressions: new FormArray<FormGroup<MediaExpressionGroupParams>>([]), }), rules: new FormControl<string>('') }); } public addMediaQuery():void{ this.MediaQueryList.push(this.createMediaQueryGroup()); } public removeMediaQuery(item: number): void{ this.MediaQueryList.removeAt(item); } }
逻辑说明
ControlValueAccessor的作用是将自定义组件封装为独立表单控件(如原生input、select),使其能与formControl等指令配合使用。而你的场景是将父组件的FormGroup拆分到子组件中进行操作,本质是共享同一个表单实例,两种模式不能混用,否则会触发表单系统的双向更新冲突,导致数据异常。
内容的提问来源于stack exchange,提问作者Optiq
相关产品推荐
相关产品推荐

