添加*ngIf至mat-selection-list外层容器后数据绑定返回undefined的问题求助
问题分析与解决方案
这问题我之前也踩过坑,核心原因是*ngIf的渲染机制搞的鬼,咱们一步步来拆解:
为什么会出现undefined?
*ngIf="!loading"这个指令的特点是:当条件不满足时,会完全销毁对应节点及其内部的所有DOM元素和组件实例。而你的<button>是放在<mat-card>外面的——
- 如果页面初始状态
loading为true,那么<mat-selection-list>压根没被渲染,你定义的#event模板引用变量根本不存在,点击按钮自然拿不到值; - 哪怕之后
loading切换为false,Angular的变更检测也没法让外部的按钮同步拿到新渲染出来的#event引用,最终还是会返回undefined。
两种可行的解决办法
方案一:把按钮移入mat-card内部(最简单直接)
让按钮和#event处于同一个*ngIf作用域里,这样只有当mat-card渲染完成时,按钮才会存在,点击时必然能拿到有效的组件引用:
<mat-card *ngIf="!loading"> <mat-card-header> <mat-card-title class="sub-title"><u>Events</u></mat-card-title> </mat-card-header> <mat-selection-list #event> <mat-list-option *ngFor="let event of listOfEvents" [value]="event.value" [selected]="event.selected" > {{event.name}} </mat-list-option> </mat-selection-list> <!-- 把按钮移到card内部,和event处于同一作用域 --> <button (click)="save(event)" class="button" type="button" >Save</button> </mat-card>
方案二:用@ViewChild获取组件实例(更灵活)
如果按钮必须放在mat-card外面,就用Angular的@ViewChild装饰器来主动获取组件实例,不需要依赖模板变量的直接传递:
首先在TS文件里引入相关依赖并声明变量:
import { Component, ViewChild } from '@angular/core'; import { MatSelectionList } from '@angular/material/list'; export class YourComponent { // 通过模板引用名绑定组件实例 @ViewChild('event') eventList!: MatSelectionList; loading = false; listOfEvents = []; // 你的事件列表数据 save(): void { // 直接通过this.eventList访问组件实例 console.log(this.eventList); // 如果需要获取选中的选项,可以用下面的代码 const selectedItems = this.eventList.selectedOptions.selected.map(opt => opt.value); console.log('选中的事件:', selectedItems); } }
然后修改模板,按钮不需要传参数:
<mat-card *ngIf="!loading"> <mat-card-header> <mat-card-title class="sub-title"><u>Events</u></mat-card-title> </mat-card-header> <mat-selection-list #event> <mat-list-option *ngFor="let event of listOfEvents" [value]="event.value" [selected]="event.selected" > {{event.name}} </mat-list-option> </mat-selection-list> </mat-card> <button (click)="save()" class="button" type="button" >Save</button>
内容的提问来源于stack exchange,提问作者piqueblinders
相关产品推荐
相关产品推荐

