Angular鼠标悬停渲染Card组件并展示详情的实现方案咨询
Angular 鼠标悬停加载卡片详情组件实现方案
我已经掌握Angular组件创建、API数据获取、*ng指令使用等技能,目前遇到技术瓶颈:
现有Hand(父组件)和Card(子组件)两个组件,Hand组件通过CardDataService的getAllCards()接口随机获取5条卡片数据并展示;需求为鼠标悬停Hand组件内的卡片时,调用CardDataService的getCardById()接口获取对应ID的详细数据,渲染Card组件展示详情,鼠标离开时销毁该组件渲染。尝试过@Input指令但未能实现ID传递与组件渲染,寻求可行实现方案。
先修复原代码中的基础错误
这些问题是导致功能无法正常运行的前提:
- Hand组件的
selector写错为app-card,与Card组件冲突,需改为app-hand - Card组件未注入
CardDataService,且getCardData方法参数传递逻辑错误 - Hand组件初始化时调用的方法名不匹配,导致卡片数据无法加载
- Card组件模板中
img标签存在语法错误,缺少闭合双引号 - 未绑定鼠标悬停/离开事件,也没有控制Card组件显示状态的逻辑
完整实现方案
1. 修改 hand.component.ts
修正组件标识、注入服务、添加事件处理逻辑:
import { Component, OnInit } from '@angular/core'; import { CardDataService } from '../../services/card-data.service'; @Component({ selector: 'app-hand', // 修正组件选择器 templateUrl: './hand.component.html', styleUrls: ['./hand.component.scss'], }) export class HandComponent implements OnInit{ hand: any[] = []; hoveredCardId: number | null = null; // 存储当前悬停卡片的ID constructor(private cardDataService: CardDataService) { } ngOnInit(): void { this.getAllCards(); // 调用正确的加载方法 } public getAllCards() { this.cardDataService.getAllCards().subscribe((response: any) => { // 优化随机选卡逻辑,避免重复选取 const cardList = [...response]; for (let i = 0; i < 5 && cardList.length > 0; i++) { const randomIndex = Math.floor(Math.random() * cardList.length); this.hand.push(cardList.splice(randomIndex, 1)[0]); } console.log(this.hand); }); } // 鼠标悬停时记录当前卡片ID onCardHover(id: number) { this.hoveredCardId = id; } // 鼠标离开时清空ID,销毁子组件 onCardLeave() { this.hoveredCardId = null; } }
2. 修改 hand.component.html
绑定鼠标事件,添加Card组件的条件渲染:
<ng-container *ngFor="let item of hand"> <div class="card-hand" (mouseenter)="onCardHover(item.id)" (mouseleave)="onCardLeave()"> <p>CARD {{ item.id }}</p> <img [src]="item.picture"> <p>{{ item.element }}</p> </div> </ng-container> <!-- 仅当hoveredCardId存在时,渲染Card子组件并传递ID --> <app-card *ngIf="hoveredCardId" [cardId]="hoveredCardId"></app-card>
3. 修改 card.component.ts
添加@Input接收ID,监听ID变化自动加载详情:
import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core'; import { CardDataService } from '../../services/card-data.service'; @Component({ selector: 'app-card', templateUrl: './card.component.html', styleUrls: ['./card.component.scss'], }) export class CardComponent implements OnInit, OnChanges{ @Input() cardId!: number; // 接收父组件传递的卡片ID public item?: any; constructor(private cardDataService: CardDataService) { } ngOnInit(): void { this.loadCardDetails(); } // 监听cardId变化,自动重新加载详情 ngOnChanges(changes: SimpleChanges): void { if (changes['cardId'] && changes['cardId'].currentValue) { this.loadCardDetails(); } } private loadCardDetails() { this.cardDataService.getCardById(this.cardId).subscribe((response: any) => { this.item = response; }); } }
4. 修改 card.component.html
修复语法错误,添加空值避免报错:
<div *ngIf="item" class="card-display"> <p>CARD {{ item.id }}</p> <p>LEVEL {{ item.level }}</p> <img [src]="item.picture"> <p>{{ item.description }}</p> <div class="card-stats"> <label>{{ item.attack }}</label> <label>{{ item.defense }}</label> </div> </div>
方案核心逻辑说明
- 组件渲染控制:通过父组件的
hoveredCardId变量结合*ngIf指令,实现Card组件的动态创建与销毁,鼠标离开时清空ID即可自动销毁组件 - 数据传递:使用
@Input()将父组件的悬停卡片ID传递给子组件,子组件通过OnChanges钩子监听ID变化,自动触发详情加载 - 事件绑定:为每个卡片容器绑定
mouseenter和mouseleave事件,实时更新当前悬停的卡片ID - 代码优化:修复原代码的语法与逻辑错误,使用属性绑定
[src]替代插值表达式提升安全性,优化随机选卡逻辑避免重复选取
内容的提问来源于stack exchange,提问作者David Encina Martínez
相关产品推荐
相关产品推荐

