Angular 12中如何在ngFor内仅触发对应索引的子组件渲染
问题描述
在Angular 12项目中,尝试在*ngFor循环内部点击按钮捕获数据并传递给子组件,期望仅在当前点击的循环索引位置渲染该子组件,但点击按钮后所有*ngFor条目下都渲染了子组件,不符合预期。
问题原因
当前实现使用全局布尔变量click控制子组件的显示状态,所有循环条目都绑定同一个变量,一旦click设为true,所有条目都会渲染子组件;同时全局变量heranca存储的选中数据也会被所有子组件共享,导致所有显示的子组件内容一致。
解决方案
通过记录当前激活的条目标识(如导演ID),让每个循环条目仅在自身标识与激活标识匹配时才渲染子组件,具体修改如下:
1. 修改父组件TS代码
将全局布尔变量click替换为activeDirectorId,用于记录当前激活的导演ID:
import { Component } from '@angular/core'; @Component({ selector: 'app-teste1', templateUrl: './teste1.component.html', styleUrls: ['./teste1.component.scss'] }) export class Teste1Component { lista = [ {nome:'Beltrano', id:1, filmes:[ { imgDesc:'community',imgPath:'../../../assets/community.jpg', nome:'Community', tipo:'Serie', duracao:'3:20'}, { imgDesc:'Avatar',imgPath:'../../../assets/avatar1.jpg', nome:'Avatar', tipo:'Filme', duracao:'3:20'}, { imgDesc:'Jujutsu no Kaisen',imgPath:'../../../assets/jjk.jpg', nome:'Jujutsu no Kaizen', tipo:'Anime', duracao:'3:20'}, { imgDesc:'Kamen Rider',imgPath:'../../../assets/kmrider.jpg', nome:'Kamem-rider', tipo:'Dorama', duracao:'3:20'}]}, {nome:'Fulano', id:2, filmes:[ { imgDesc:'community',imgPath:'../../../assets/community.jpg' ,nome:'Community', tipo:'Serie', duracao:'3:20'}, { imgDesc:'Avatar',imgPath:'../../../assets/avatar1.jpg' ,nome:'Avatar', tipo:'Filme', duracao:'3:20'}, { imgDesc:'Jujustu no Kaisen',imgPath:'../../../assets/jjk.jpg' ,nome:'Jujutsu no Kaizen', tipo:'Anime', duracao:'3:20'}, { imgDesc:'Kamen Rider',imgPath:'../../../assets/kmrider.jpg' ,nome:'Kamem-rider', tipo:'Dorama', duracao:'3:20'}]}, {nome:'Ciclano', id:3, filmes:[ { imgDesc:'community',imgPath:'../../../assets/community.jpg' ,nome:'Community', tipo:'Serie', duracao:'3:20'}, { imgDesc:'Avatar',imgPath:'../../../assets/avatar1.jpg' ,nome:'Avatar', tipo:'Filme', duracao:'3:20'}, { imgDesc:'Jujutsu no Kaisen',imgPath:'../../../assets/jjk.jpg' ,nome:'Jujutsu no Kaizen', tipo:'Anime', duracao:'3:20'}, { imgDesc:'Kamen Rider',imgPath:'../../../assets/kmrider.jpg' ,nome:'Kamem-rider', tipo:'Dorama', duracao:'3:20'}]}, {nome:'Giclano', id:4, filmes:[ { imgDesc:'community',imgPath:'../../../assets/community.jpg' ,nome:'Community', tipo:'Serie', duracao:'3:20'}, { imgDesc:'Avatar',imgPath:'../../../assets/avatar1.jpg' ,nome:'Avatar', tipo:'Filme', duracao:'3:20'}, { imgDesc:'Jujutsu no Kaisen',imgPath:'../../../assets/jjk.jpg' ,nome:'Jujutsu no Kaizen', tipo:'Anime', duracao:'3:20'}, { imgDesc:'Kamen Rider',imgPath:'../../../assets/kmrider.jpg' ,nome:'Kamem-rider', tipo:'Dorama', duracao:'3:20'}]}, ] heranca: any activeDirectorId?: number // 替换原click变量,记录当前激活的导演ID array: any[] = [] openDetails(id:number, filme:any){ // 点击同一导演的按钮时切换显示/隐藏 this.activeDirectorId = this.activeDirectorId === id ? undefined : id; this.heranca = { id_diretor:id, nome: filme.nome, tipo: filme.tipo, duracao: filme.duracao, descricao: "Filme ou série xpto" } this.saveIntoArray(this.heranca) } saveIntoArray(filme: any){ this.array.push(filme) console.log(this.array) } }
2. 修改父组件HTML代码
将子组件的显示条件改为判断当前条目的导演ID是否与激活ID一致:
<div class="main-container"> <div class="container"> <div *ngFor="let pessoa of lista; index as i" class="media-controler "> <div class="director-container"> <div class="details"> <span class="person"> Diretor </span> <span class="person-name"> {{pessoa.nome}}</span> </div> </div> <div class="slider" *ngFor="let x of pessoa.filmes"> <mat-card class="example-card mat-elevation-z8"> <mat-card-header> <mat-card-subtitle>{{x.tipo}}</mat-card-subtitle> <mat-card-title>{{ x.nome}}</mat-card-title> </mat-card-header> <img mat-card-image src="{{x.imgPath}}" class="imgPath" alt="{{x.imgDesc}}"> <mat-divider></mat-divider> <mat-card-actions> <button mat-button color="primary" (click)="openDetails(pessoa.id, x);" >Detalhes</button> </mat-card-actions> </mat-card> </div> <!-- 仅当前激活的导演条目渲染子组件 --> <ng-container *ngIf="activeDirectorId === pessoa.id"> <app-teste2 [objFilme]="heranca"></app-teste2> </ng-container> </div> </div> </div>
说明
- 使用
activeDirectorId记录当前点击的导演ID,每个循环条目独立判断是否需要渲染子组件,确保只有点击的条目才显示子组件。 - 增加了切换逻辑:再次点击同一导演的按钮时,会隐藏子组件,提升交互体验。
内容的提问来源于stack exchange,提问作者halfbit
相关产品推荐
相关产品推荐

