Angular的ngFor循环中如何实现选中单个组件其余自动取消选中
Angular单选答案交互实现方案
核心原理
你当前的问题是每个答案组件各自维护选中状态,导致选中新答案时其他组件的状态无法同步更新。我们需要把选中状态的控制权上移到父组件ExamInProgress统一管理,父组件记录当前选中的答案,再把选中状态下发给每个答案子组件,即可实现单选互斥效果。
代码修改步骤
1. 修改答案组件(AnswerComponent)
移除内部维护的选中状态逻辑,改为接收父组件传入的选中状态,点击时仅触发选中事件通知父组件。
answer.component.ts
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'; import { Answer } from 'src/app/_models/answer'; @Component({ selector: 'app-answer', templateUrl: './answer.component.html', styleUrls: ['./answer.component.css'] }) export class AnswerComponent implements OnInit { @Input() answer: Answer; // 选中状态改为父组件传入 @Input() isAnswerChosen: boolean = false; @Output() onAnswerChosen = new EventEmitter<Answer>(); constructor() { } ngOnInit(): void { } onClick() { // 仅触发选中事件,不再自行修改状态 this.onAnswerChosen.emit(this.answer); } }
answer.component.html 无需修改,保持原有逻辑即可
2. 修改考试进行中组件(ExamInProgressComponent)
利用已有的chosenAnswer变量记录当前选中的答案,切换题目时清空选中状态即可。
exam-in-progress.component.ts
只需修改onNextClick方法,切换题目时清空上一题的选中答案:
onNextClick() { // 清空上一题选中状态 this.chosenAnswer = null; this.currentQuestion = this.questions[1]; this.currentAnswers = this.answers.filter(answer => answer.questionId === 3); this.shuffle(this.currentAnswers); if(this.isChosenAnswerCorrect()) { console.log('correct'); } else { console.log('incorrect'); } }
原有其他逻辑不需要修改。
3. 修改父组件模板(exam-in-progress.component.html)
循环渲染答案组件时,传入每个答案的选中状态判断:
<p *ngIf="user && currentUser$ | async">{{user.firstName}} {{user.lastName}}</p> <app-question [question]="currentQuestion"></app-question> <div class="answers"> <app-answer (onAnswerChosen)="getChosenAnswerData($event)" *ngFor="let answer of currentAnswers" [answer]="answer" [isAnswerChosen]="answer.id === chosenAnswer?.id" ></app-answer> </div> <app-timer></app-timer> <button type="button" (click)="onNextClick()">next</button>
完成以上修改后,点击任意答案时父组件会更新chosenAnswer,所有答案组件的选中状态会自动重新计算,仅当前选中的答案会显示选中态背景色,自动实现互斥效果。
内容的提问来源于stack exchange,提问作者rardav
相关产品推荐
相关产品推荐

