Angular 14中ngFor内color类型input无法修改值的问题
Angular ^14.2.0 中Color类型Input无法修改的问题解决
问题原因
notWorkingForm模板中使用*ngFor="let field of foo.toForm().fields"时,每次Angular触发变更检测都会调用foo.toForm()方法,返回一个全新的fields数组对象。Angular会将新数组识别为数据源变更,进而销毁并重新渲染所有循环生成的输入组件。
对于type="color"的输入框,用户选择颜色后,组件还没来得及将新值同步到FormControl,就被Angular销毁重建,导致值被重置为初始值;而number类型输入因为是实时按键输入,组件重建前已经完成了值同步,所以看起来正常。
解决方案
将foo.toForm()的结果缓存到组件属性中,避免在模板中直接调用方法生成新数组:
1. 修改组件代码(app.component.ts)
添加缓存字段并在初始化时赋值:
export class AppComponent { notWorkingForm: FormGroup = new FormGroup<any>({}); workingForm: FormGroup = new FormGroup<any>({}); fieldsDescription: IndicatorEditForm = { /* 原有代码保持不变 */ }; foo: Foo = new Foo(); // 新增缓存字段 fooFormFields: IndicatorEditFormField[]; constructor() { // 缓存foo的表单字段 this.fooFormFields = this.foo.toForm().fields; // 原有表单初始化逻辑不变 this.fooFormFields.forEach(field => { this.notWorkingForm.addControl(field.name, new FormControl(field.value)); }); // 其余原有代码保持不变 this.fieldsDescription.fields.forEach(field => { this.workingForm.addControl(field.name, new FormControl(field.value)); }); this.workingForm.valueChanges.subscribe(value => { console.log('working', value); }); this.notWorkingForm.valueChanges.subscribe(value => { console.log('now working', value); }); } }
2. 修改模板代码(app.component.html)
将ngFor的数据源替换为缓存的属性:
<h2>Now working</h2> <form [formGroup]="notWorkingForm" class="row align-items-center"> <div class="col"> <div class="row"> <ng-container *ngFor="let field of fooFormFields"> <div class="input-group mb-3"> <span class="input-group-text">{{field.label}}</span> <input [type]="field.type" [formControlName]="field.name"> </div> </ng-container> </div> </div> </form> <!-- 第二个表单代码保持不变 --> <h2>Working</h2> <form [formGroup]="workingForm" class="row align-items-center"> <div class="col"> <div class="row"> <ng-container *ngFor="let field of fieldsDescription.fields"> <div class="input-group mb-3"> <span class="input-group-text">{{field.label}}</span> <input [type]="field.type" [formControlName]="field.name"> </div> </ng-container> </div> </div> </form>
原理说明
缓存后的fooFormFields是固定的数组引用,Angular变更检测时不会识别为数据源变更,输入组件不会被频繁销毁重建。用户选择颜色后,新值能正常同步到对应的FormControl,valueChanges也会正常触发。
内容的提问来源于stack exchange,提问作者Efae
相关产品推荐
相关产品推荐

