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

Angular项目中mat-list绑定formControlName报错的单选无复选框方案求助

解决Angular Material mat-list绑定formControlName的问题

这个问题我之前也碰到过,核心原因是mat-list本身并不是Angular表单的原生控件,没有实现ControlValueAccessor接口,所以直接添加formControlName就会触发"No value accessor..."的报错。而mat-selection-list虽然支持表单绑定,但默认的多选和复选框确实不符合你的需求,下面给你两种可行的解决方案:


方案1:改造mat-selection-list实现单选并隐藏复选框

这是最快捷的方案,利用mat-selection-list本身的表单支持能力,通过配置和CSS改造来达到你的需求:

步骤1:配置单选模式

给mat-selection-list添加[multiple]="false"属性,将其切换为单选模式:

<form [formGroup]="myForm">
  <mat-selection-list formControlName="selectedItem" [multiple]="false">
    <mat-list-option *ngFor="let option of options" [value]="option.id">
      {{ option.label }}
    </mat-list-option>
  </mat-selection-list>
</form>

步骤2:隐藏复选框

通过CSS隐藏默认的复选框,注意使用:host ::ng-deep来确保样式只作用于当前组件内的列表:

:host ::ng-deep .mat-pseudo-checkbox {
  display: none;
}

/* 可选:给选中项添加背景色,提升用户体验 */
:host ::ng-deep .mat-list-option[aria-selected="true"] {
  background-color: rgba(0, 0, 0, 0.04);
}

组件类代码示例

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-single-select-list',
  templateUrl: './single-select-list.component.html',
  styleUrls: ['./single-select-list.component.css']
})
export class SingleSelectListComponent implements OnInit {
  myForm: FormGroup;
  options = [
    { id: 'opt1', label: '选项1' },
    { id: 'opt2', label: '选项2' },
    { id: 'opt3', label: '选项3' }
  ];

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    this.myForm = this.fb.group({
      selectedItem: ['opt1'] // 设置默认选中值
    });
  }
}

方案2:为mat-list自定义ControlValueAccessor

如果你希望完全基于mat-list实现表单绑定,可以自定义一个封装组件,实现Angular表单的ControlValueAccessor接口:

步骤1:创建自定义组件

import { Component, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-single-select-mat-list',
  templateUrl: './single-select-mat-list.component.html',
  styleUrls: ['./single-select-mat-list.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => SingleSelectMatListComponent),
      multi: true
    }
  ]
})
export class SingleSelectMatListComponent implements ControlValueAccessor {
  @Input() options: { id: string; label: string }[] = [];
  selectedValue: string | null = null;

  // 表单控件回调函数
  onChange: (value: string | null) => void = () => {};
  onTouched: () => void = () => {};

  // 实现ControlValueAccessor接口方法:写入表单值
  writeValue(value: string | null): void {
    this.selectedValue = value;
  }

  // 注册值变化回调
  registerOnChange(fn: (value: string | null) => void): void {
    this.onChange = fn;
  }

  // 注册触摸回调
  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  // 处理列表项点击事件
  handleItemClick(optionId: string): void {
    this.selectedValue = optionId;
    this.onChange(optionId);
    this.onTouched();
  }
}

步骤2:自定义组件模板

<mat-list>
  <mat-list-item 
    *ngFor="let option of options"
    [class.selected]="selectedValue === option.id"
    (click)="handleItemClick(option.id)"
  >
    {{ option.label }}
  </mat-list-item>
</mat-list>

步骤3:添加选中样式

.mat-list-item.selected {
  background-color: rgba(0, 0, 0, 0.04);
  cursor: pointer;
}

父组件中使用自定义组件

<form [formGroup]="myForm">
  <app-single-select-mat-list 
    formControlName="selectedItem"
    [options]="options"
  ></app-single-select-mat-list>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:38:35