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

Angular 16中cdkListbox内mat-checkbox点击后视觉状态不更新

Angular 16 + CDK Listbox 嵌套 Mat-Checkbox 视觉更新异常问题

问题现象

使用Angular 16搭配Angular Material开发组件,采用cdkListbox并嵌套mat-checkbox时:

  • 点击listbox内的选项区域,选中模型数组已变更,但checkbox的视觉状态未同步更新;
  • 在cdkList外部切换同绑定的checkbox时,视觉状态可正常切换。

问题原因

当前代码中,cdkListbox的选中状态(starter数组)与mat-checkbox绑定的pokemon.selected状态相互独立。点击cdkOption时仅更新了starter数组,未同步修改pokemon.selected的值,导致mat-checkbox因绑定值未变化而无法触发视觉更新。

解决方案

通过双向绑定cdkOption的选中状态与pokemon.selected,实现两者状态完全同步:

修改后的模板代码

<div class="example-listbox-container">
  <label class="example-listbox-label" id="example-starter-pokemon-label">
    Starter Pokemon
  </label>
  {{ starters | json }}
  <ul
    cdkListbox
    [cdkListboxValue]="starters.filter(p => p.selected)"
    aria-labelledby="example-starter-pokemon-label"
    class="example-listbox"
  >
    <li
      *ngFor="let pokemon of starters"
      [cdkOption]="pokemon"
      [cdkOptionSelected]="pokemon.selected"
      (cdkOptionSelectedChange)="pokemon.selected = $event"
      class="example-option"
    >
      <mat-checkbox [(ngModel)]="pokemon.selected"> {{pokemon.name}} </mat-checkbox>
    </li>
  </ul>

  Toggling the below checkboxes changes the visual state of the above checkboxes
 <ul>
  <li><mat-checkbox [(ngModel)]="starters[0].selected"> {{starters[0].name}} </mat-checkbox></li>
  <li><mat-checkbox [(ngModel)]="starters[1].selected"> {{starters[1].name}} </mat-checkbox></li>
  <li><mat-checkbox [(ngModel)]="starters[2].selected"> {{starters[2].name}} </mat-checkbox></li>
 </ul>

</div>
<p>
  Your starter pokemon is <strong>{{starters.filter(p => p.selected) | json}}</strong>&nbsp;
</p>

修改后的组件代码

import { Component } from '@angular/core';
import { NgFor, JsonPipe, CommonModule } from '@angular/common';
import { CdkListbox, CdkOption } from '@angular/cdk/listbox';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { FormsModule } from '@angular/forms';

interface PokemonModel {
  id: string;
  name: string;
  selected: boolean;
}

@Component({
  selector: 'cdk-listbox-value-binding-example',
  exportAs: 'cdkListboxValueBindingExample',
  templateUrl: 'cdk-listbox-value-binding-example.html',
  styleUrls: ['cdk-listbox-value-binding-example.css'],
  standalone: true,
  imports: [
    CdkListbox,
    NgFor,
    CdkOption,
    JsonPipe,
    MatCheckboxModule,
    FormsModule,
    CommonModule,
  ],
})
export class CdkListboxValueBindingExample {
  starters: PokemonModel[] = [
    { id: '1', name: 'Sprigatito', selected: false },
    { id: '2', name: 'Fuecoco', selected: false },
    { id: '3', name: 'Quaxly', selected: false },
  ];
}

关键调整说明

  1. 绑定cdkOption选中状态:通过[cdkOptionSelected]="pokemon.selected"将选项的选中状态与模型值绑定;
  2. 同步模型值变更:通过(cdkOptionSelectedChange)="pokemon.selected = $event"实现选项选中状态变化时,同步更新pokemon.selected的值;
  3. 简化选中值逻辑:cdkListboxValue直接通过过滤starters数组获取选中项,无需单独维护starter变量,避免状态不一致;
  4. 双向同步生效:此时点击cdkOption任意区域(包括checkbox),都会同步更新pokemon.selected与checkbox的视觉状态,外部checkbox的操作也会同步到内部的cdkOption选中状态。

内容的提问来源于stack exchange,提问作者Stephen E.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:20:36