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

Angular嵌套*ngFor列表中选择Part却显示对应Mechanism的问题

问题分析与解决方案

你的问题核心是事件冒泡:点击子项(Part)时,点击事件会向上冒泡到父级的<div>元素,导致父级的chooseNew(selection.id)也被触发。控制台会先记录Part的ID,紧接着又被所属Mechanism的ID覆盖,最终详情组件显示Mechanism内容。

解决方法

方法1:阻止子项事件冒泡

修改PortfolioNavComponent.html中嵌套的<li>点击事件,添加$event.stopPropagation()阻止事件向上传递:

<section class="flipped">
  <ul>
    <div *ngFor="let selection of selections" (click)="chooseNew(selection.id)">
      <li>{{selection.name}}</li>
      <ul>
        <li *ngFor="let subselection of selection.parts" (click)="chooseNew(subselection.id); $event.stopPropagation()">{{subselection.name}}</li>
      </ul>
    </div>
  </ul>
</section>

方法2:调整DOM结构(更规范)

将父级点击事件从包裹子列表的<div>移到Mechanism对应的<li>上,避免父元素覆盖子列表区域,从根源减少冒泡影响:

<section class="flipped">
  <ul>
    <li *ngFor="let selection of selections" (click)="chooseNew(selection.id)">
      {{selection.name}}
      <ul>
        <li *ngFor="let subselection of selection.parts" (click)="chooseNew(subselection.id); $event.stopPropagation()">{{subselection.name}}</li>
      </ul>
    </li>
  </ul>
</section>

额外优化:替换setTimeout为响应式监听

你当前用setTimeout等待数据加载的方式不够可靠,建议改用Angular响应式编程模式:

  1. 在PortfolioService中定义BehaviorSubject存储数据:
private mechanismsSubject = new BehaviorSubject<Mechanism[]>([]);
public mechanisms$ = this.mechanismsSubject.asObservable();

getData() {
  return this.http.get<Mechanism[]>('你的API地址').pipe(
    tap(data => this.mechanismsSubject.next(data))
  );
}
  1. 在PortfolioNavComponent中订阅数据更新:
ngOnInit(): void {
  this.portfolioService.mechanisms$.subscribe(() => {
    this.selections = this.portfolioService.getSelections();
  });
}

这样数据加载完成后组件会自动更新,无需依赖固定延迟的setTimeout。

内容的提问来源于stack exchange,提问作者Stiofán

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:17:56