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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:48:43