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响应式编程模式:
- 在
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)) ); }
- 在
PortfolioNavComponent中订阅数据更新:
ngOnInit(): void { this.portfolioService.mechanisms$.subscribe(() => { this.selections = this.portfolioService.getSelections(); }); }
这样数据加载完成后组件会自动更新,无需依赖固定延迟的setTimeout。
内容的提问来源于stack exchange,提问作者Stiofán
相关产品推荐
相关产品推荐

