You need to enable JavaScript to run this app. Angular 10中FormControl初始化mat-selection-list选项不勾选问题
优惠活动
大模型
产品
解决方案
定价
更多

Angular 10中FormControl初始化mat-selection-list选项不勾选问题

问题核心根源

你遇到的列表选项不勾选的问题,是两个实现细节疏漏叠加导致的:

  • Material 的 mat-selection-list 判断选项选中状态的逻辑,是对 FormControl 的值和每个 mat-list-option 绑定的 value 做严格相等(===)匹配。你现在在选项上绑了整个 cat 对象作为value,而 FormControl 初始存的 this.user.lstCategory 是接口返回的独立对象实例,哪怕两个对象的字段、值完全一致,只要内存引用不同,匹配就会失败,自然不会触发选中状态。
  • 两个异步服务请求的执行时序存在不可控风险:你把表单初始化逻辑绑在 getUser 请求的完成回调里,但 getAllCategory 是独立发起的异步请求,完全可能出现表单已经初始化完成、分类列表数据还没返回的情况,此时 mat-selection-list 连选项都没渲染全,就算值的引用一致,也没法匹配到对应选项。
具体修复步骤
  • 调整选项绑定的value,不要直接绑定整个分类对象,改用分类对象上的**唯一稳定标识(比如分类id)**作为选项值,从根源上避免对象引用匹配的问题。
  • 调整FormControl的初始值格式,把用户信息里的分类对象数组,映射成和选项值一致的纯标识数组,确保两边的值可以通过严格相等校验。
  • 梳理异步请求的执行时序,等两个接口都返回数据之后,再初始化表单和渲染组件,避免出现数据加载的空窗期。
调整后的参考代码

首先是TS逻辑调整:

// 引入forkJoin用于合并多个异步请求
import { forkJoin } from 'rxjs';

ngOnInit(): void {
  // 合并两个独立的异步请求,等全部响应完成再执行后续逻辑
  forkJoin({
    cbxCategory: this.categoryService.getAllCategory(),
    user: this.authService.getUser()
  }).subscribe({
    next: (res) => {
      this.cbxCategory = res.cbxCategory;
      this.user = res.user;
    },
    error: (err) => console.log(err),
    // 两个请求都完成后再初始化表单
    complete: () => this.initForm()
  })
}

private initForm() {
  this.editUserForm = this.formBuilder.group({
    email: new FormControl(this.user.email, [Validators.required,Validators.pattern("^[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,6}$"),Validators.maxLength(50)]),
    password: new FormControl(''),
    passwordConfirm: new FormControl(''),
    // 把用户的分类数组映射为和选项value一致的id数组
    lstCat: new FormControl(this.user.lstCategory.map(item => item.id)),
  }, {
    validator: MustMatch('password', 'passwordConfirm')
  });
}

然后是HTML模板调整:

<mat-selection-list formControlName="lstCat" class="col-md-12 col-sm-12">
  <!-- 把原来绑定整个cat对象的value改成绑定cat的唯一id -->
  <mat-list-option *ngFor="let cat of cbxCategory" [value]="cat.id">
    {{cat.libelle}}
  </mat-list-option>
</mat-selection-list>

补充说明:如果业务逻辑需要获取选中选项的完整对象信息,不需要把value直接绑整个对象,可以在表单提交时,根据FormControl里存的id数组,从cbxCategory列表中过滤匹配出对应的完整对象即可,既可以规避引用匹配的问题,也能降低组件的内存占用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 02:06:09