Angular14基于搜索结果展开指定mat-accordion面板问题排查
问题排查结果
你的代码存在3个核心逻辑错误,导致面板展开不符合预期:
- 展开状态存储设计错误:已开启
mat-accordion的multi="true"多面板展开模式,却用单个数字变量step存储展开索引,该设计最多仅支持1个面板展开,和多展开模式完全冲突。 - 条件判断语法错误:
if(this.search != '' || undefined)为无效写法,受运算符优先级影响,空值校验逻辑完全失效,搜索词为空时不会更新step值,step一直保持初始值0,因此始终默认展开第一个面板。 - 遍历赋值逻辑错误:
forEach循环中无论当前面板是否匹配搜索词,都会执行this.step = index覆盖之前的值,循环结束后step只会是最后一个遍历项的索引,根本无法记录匹配项的位置。
修复方案
1. 修改组件TS逻辑
替换单个数字的展开标记,改用集合存储所有需要展开的面板索引,修正判断和遍历逻辑:
import { Component, OnInit } from '@angular/core'; import { CommonService } from '../service/common.service'; import { GlossaryOfTerms } from '../model/GlossaryOfTerms.model'; @Component({ selector: 'app-terms', templateUrl: './terms.component.html', styleUrls: ['./terms.component.scss'] }) export class GlossaryOfTermsComponent implements OnInit { search: string = ""; gTerms: GlossaryOfTerms[] = []; // 用集合存储所有需要展开的面板索引,适配多面板展开场景 expandedPanelIndexes = new Set<number>(); constructor(private commonService: CommonService) {} ngOnInit(): void { this.getTerms(); } public OnSearched(searchTerm: string) { this.search = searchTerm.trim(); this.findSearchedValue(); } getTerms(): void { this.commonService.getGlossaryOfTerms().subscribe((terms) => { this.gTerms = terms; // 初始默认展开第一个面板 this.expandedPanelIndexes.add(0); }); } findSearchedValue(): void { // 清空历史展开状态 this.expandedPanelIndexes.clear(); // 搜索词为空时恢复默认展开第一个面板 if (!this.search) { this.expandedPanelIndexes.add(0); return; } // 仅将匹配搜索词的面板索引加入展开集合 this.gTerms?.forEach((term, index) => { // 补全空值兜底,新增大小写不敏感匹配(不需要可删除toLowerCase逻辑) const description = term.description?.toLowerCase() || ''; const name = term.name?.toLowerCase() || ''; const keyword = this.search.toLowerCase(); if (description.includes(keyword) || name.includes(keyword)) { this.expandedPanelIndexes.add(index); } }); } // 手动切换面板展开状态 togglePanel(index: number) { if (this.expandedPanelIndexes.has(index)) { this.expandedPanelIndexes.delete(index); } else { this.expandedPanelIndexes.add(index); } } }
2. 修改模板绑定逻辑
替换原来的单值展开判断,绑定集合的包含判断,补充手动点击面板的状态切换事件:
<app-search #searchedValue (searched)="OnSearched($event)"></app-search> <mat-accordion multi="true"> <mat-expansion-panel #accordianContainer *ngFor="let term of gTerms; let i = index" [expanded]="expandedPanelIndexes.has(i)" (opened)="togglePanel(i)" (closed)="togglePanel(i)" > <mat-expansion-panel-header> <mat-panel-title> <p [innerHTML]="term.name | highlightSearch: search"></p> </mat-panel-title> </mat-expansion-panel-header> <div class="content"> <div class="content-text"> <p [innerHTML]="term.description | highlightSearch: search"></p> </div> </div> </mat-expansion-panel> </mat-accordion>
补充说明
- 修复后支持同时展开所有匹配搜索词的面板,符合
multi="true"的配置预期 - 新增的大小写不敏感匹配为可选优化,不需要可直接删除
toLowerCase相关代码 - 原代码中
decription为拼写错误,正确拼写为description,建议修正避免后续维护问题
内容的提问来源于stack exchange,提问作者Vjdpa
相关产品推荐
相关产品推荐

