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> </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 }, ]; }
关键调整说明
- 绑定
cdkOption选中状态:通过[cdkOptionSelected]="pokemon.selected"将选项的选中状态与模型值绑定; - 同步模型值变更:通过
(cdkOptionSelectedChange)="pokemon.selected = $event"实现选项选中状态变化时,同步更新pokemon.selected的值; - 简化选中值逻辑:
cdkListboxValue直接通过过滤starters数组获取选中项,无需单独维护starter变量,避免状态不一致; - 双向同步生效:此时点击
cdkOption任意区域(包括checkbox),都会同步更新pokemon.selected与checkbox的视觉状态,外部checkbox的操作也会同步到内部的cdkOption选中状态。
内容的提问来源于stack exchange,提问作者Stephen E.
相关产品推荐
相关产品推荐

