You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:47:49