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

Reactive Form中FormArray的mat-select如何让valueChanges首次触摸即响应

问题根源

你当前的实现逻辑存在订阅时机错误:每次触发selectionChange事件时才去订阅valueChanges,但第一次选择操作完成后,控件值已经更新完毕,此时新订阅的valueChanges只会监听后续的数值变化,因此第一次操作不会触发回调逻辑。

解决方案

方案一:提前订阅(推荐,避免重复订阅与内存泄漏)

在FormArray的控件初始化阶段就完成valueChanges的订阅,无需依赖selectionChange事件。

代码示例

// 假设在组件初始化时创建FormArray
constructor(private fb: FormBuilder) {}

ngOnInit(): void {
  this.initFormArray();
}

private initFormArray(): void {
  this.form = this.fb.array([]);
  
  // 循环为每个分类创建表单控件并订阅valueChanges
  this.Categories.forEach((_, index) => {
    const control = this.fb.control(''); // 根据业务设置初始值
    this.form.push(control);

    control.valueChanges.pipe(
      switchMap((categoryId: any) => {
        return this.service.getDataByCategoryTypeAndProperty(categoryId, this.propertyId);
      })
    ).subscribe(data => {
      // 若需对应每个FormArray项存储数据,建议改用数组:this.gatDataArray[index] = data
      this.gatData = data;
    });
  });
}

模板修改

移除(selectionChange)绑定,仅保留表单控件关联:

<mat-form-field>
  <mat-label>Service</mat-label>
  <mat-select formControlName="categoryId">
    <mat-option *ngFor="let category of Categories" [value]="category.categoryId">
      {{category.categoryName}}
    </mat-option>
  </mat-select>
</mat-form-field>

方案二:保留selectionChange,添加startWith触发初始值

如果必须保留selectionChange事件,可通过startWith操作符让订阅立即触发一次当前控件的数值(包括刚选择的值),同时需注意避免重复订阅导致的内存泄漏。

代码示例

import { takeUntil, startWith } from 'rxjs';
import { Subject } from 'rxjs';

private destroy$ = new Subject<void>();

doSomething(i: number) {
  const control = this.form.at(i);
  
  control.valueChanges.pipe(
    startWith(control.value), // 立即触发当前值的回调
    switchMap((categoryId: any) => {
      return this.service.getDataByCategoryTypeAndProperty(categoryId, this.propertyId);
    }),
    takeUntil(this.destroy$) // 组件销毁时取消订阅,避免内存泄漏
  ).subscribe(data => {
    this.gatData = data;
  });
}

ngOnDestroy(): void {
  this.destroy$.next();
  this.destroy$.complete();
}
注意事项

如果gatData需要对应FormArray的每一项数据,建议使用数组存储(如this.gatDataArray: any[] = []),避免单个变量被多次选择操作覆盖。

内容的提问来源于stack exchange,提问作者Yoni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30