Angular实现DnD游戏参与者轮次高亮及切换功能问题
DnD回合制面板高亮问题解决思路与优化方案
我来帮你梳理下这个问题的核心问题,以及你最终方案可行的原因,顺便再给你点小优化建议~
最初绑定失效的原因
你一开始用ngClass没生效,问题出在判断条件上:
[ngClass]="{selected: selectedParticipant == participant[i]}"
这里犯了两个小错误:
participant已经是*ngFor循环里的当前参与者对象,participant[i]这种写法完全不对selectedParticipant是数字类型的索引值,你拿对象和数字做对比,类型不匹配,自然不会触发样式绑定
正确的高亮实现方式
要实现当前回合参与者的高亮,核心是把循环的索引和selectedParticipant绑定的索引做匹配,下面两种方式都能实现:
方式1:用ngClass绑定(更符合Angular风格)
直接给参与者的容器div绑定ngClass,这样能给整个卡片加高亮样式,比只给图片绑定更合理:
<div class="heroWrapper"> <div class="image hero" *ngFor="let participant of participants; index as i" [ngClass]="{'selected': i === selectedParticipant}" > <img [src]="participant.imageUrl" /> <span class="HP">{{participant.hitPoints}}</span> <span class="namePlayer" *ngIf="isHero(participant)"> {{getPlayerName(participant)}}</span> <span class="nameHero">{{participant.name}}</span> </div> </div>
之后你只需要在CSS里定义.selected的高亮样式(比如加个彩色边框、背景色)就行。
方式2:动态拼接类名(你最终采用的方案)
你最后用的[class]动态绑定写法也完全没问题,逻辑很直观:匹配索引时用高亮类,否则用默认类:
<div class="heroWrapper"> <div *ngFor="let participant of participants; index as i" [class]="i === selectedParticipant ? 'selected hero' : 'image hero'" > <img [src]="participant.imageUrl" /> <span class="HP">{{participant.hitPoints}}</span> <span class="namePlayer" *ngIf="isHero(participant)"> {{getPlayerName(participant)}}</span> <span class="nameHero">{{participant.name}}</span> </div> </div>
额外优化:简化回合循环逻辑
你的previous()和next()方法可以用取模运算简化,不用写条件判断也能实现循环:
next(){ // 加1后取模,自动回到第一个 this.selectedParticipant = (this.selectedParticipant + 1) % this.participants.length; } previous(){ // 减1后加数组长度再取模,避免负数索引 this.selectedParticipant = (this.selectedParticipant - 1 + this.participants.length) % this.participants.length; }
这样不管点击多少次按钮,索引都会在合法范围内循环,逻辑更简洁健壮。
内容的提问来源于stack exchange,提问作者Audiosleef
相关产品推荐
相关产品推荐

