angular - 如何在角度 ng-For 中选择一个组件并取消选择其他组件?
问题描述
我正在使用 Angular 开发一个测验应用程序。我的考试进行中组件由一个问题组件和 4 个答案组件组成。用户一次只能选择一个答案。我试图实现的行为是当我选择一个答案时,我想为其背景着色并取消其他答案的背景颜色,因此取消选择它们。如何做到这一点?
答案组件
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
@Output() onAnswerChosen = new EventEmitter<Answer>();
isAnswerChosen: boolean = false;
constructor() { }
ngOnInit(): void {
}
onClick() {
this.chooseAnswer();
this.changeAnswerColor();
}
public chooseAnswer(): void {
this.onAnswerChosen.emit(this.answer);
}
changeAnswerColor() {
this.isAnswerChosen = !this.isAnswerChosen;
}
}
<div
(click)="onClick()"
class="container"
[ngStyle] = "{
'backgroundColor': isAnswerChosen ? 'red' : 'green'
}"
>
<h4 *ngIf="answer">{{answer.id}} - {{answer.text}}</h4>
</div>
进行中的考试组件
import { formatDate } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Answer } from 'src/app/_models/answer';
import { IndividualSession } from 'src/app/_models/individual-session';
import { Question } from 'src/app/_models/question';
import { User } from 'src/app/_models/user';
import { AccountService } from 'src/app/_services/account.service';
import { AnswersService } from 'src/app/_services/answers.service';
import { IndividualSessionService } from 'src/app/_services/individual-session.service';
import { NavbarService } from 'src/app/_services/navbar.service';
import { QuestionsService } from 'src/app/_services/questions.service';
import { UsersService } from 'src/app/_services/users.service';
@Component({
selector: 'app-exam-in-progress',
templateUrl: './exam-in-progress.component.html',
styleUrls: ['./exam-in-progress.component.css']
})
export class ExamInProgressComponent implements OnInit {
individualSession: IndividualSession;
user: User;
currentUser$: Observable<User>;
questions: Question[];
currentQuestion: Question;
answers: Answer[];
currentAnswers: Answer[];
chosenAnswer: Answer;
constructor(public navService: NavbarService,
public individualSessionService: IndividualSessionService,
public userService: UsersService,
public accountService: AccountService,
private questionService: QuestionsService,
private answerService: AnswersService) { }
ngOnInit(): void {
this.navService.hide();
this.startNewSession();
}
private startNewSession() {
this.getCurrentUserData();
if (localStorage.getItem('currentIndividualSession') === null) {
this.individualSession = <IndividualSession>{
ability: 0.5,
standardError: 1,
startTime: formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss', 'en-us'),
examineeId: 1,
sessionId: 1
};
localStorage.setItem('currentIndividualSession', JSON.stringify(this.individualSession));
}
let json = localStorage.getItem('currentIndividualSession');
this.individualSession = JSON.parse(json);
this.loadData();
}
//=========================================================== events
onNextClick() {
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');
}
}
//===========================================================
private getCurrentUserData() {
this.currentUser$ = this.accountService.currentUser$;
this.currentUser$.subscribe(currUser => {
if(!!currUser) {
this.loadUser(currUser.email);
}
})
}
loadUser(email: string) {
this.userService.getUser(email).subscribe(user => {
this.user = user;
})
}
loadData() {
this.questionService.getQuestionsFromQuestionnaire(1).subscribe(questions => {
this.questions = questions;
this.currentQuestion = questions[0];
this.loadAnswers();
});
}
loadAnswers() {
this.answerService.getAnswers().subscribe(answers => {
this.answers = answers;
this.currentAnswers = this.answers.filter(answer => answer.questionId === this.currentQuestion.id);
this.shuffle(this.currentAnswers);
});
}
shuffle(array: Answer[]) {
var currentIndex = array.length, temporaryValue: Answer, randomIndex: number;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
getChosenAnswerData(answer: Answer) {
this.chosenAnswer = answer;
}
isChosenAnswerCorrect() {
return this.chosenAnswer.isCorrect;
}
}
<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"></app-answer>
</div>
<app-timer></app-timer>
<button type="button" (click)="onNextClick()">next</button>
解决方案
创建一个类 -
.red { background-color:red;}
为所有 4 个答案组件创建参考变量,并在点击函数中发送所有 4 个参考变量,第五个变量将是当前点击的元素-
<answer1 #ans1 (click)="changeBackgroundColor(ans1,ans2,ans3,ans4, ans1)"></answer1>
<answer2 #ans2 (click)="changeBackgroundColor(ans1,ans2,ans3,ans4, ans2)"></answer2>
<answer3 #ans3 (click)="changeBackgroundColor(ans1,ans2,ans3,ans4, ans3)"></answer3>
<answer4 #ans4 (click)="changeBackgroundColor(ans1,ans2,ans3,ans4, ans4)"></answer4>
在单击功能中,首先从所有 4 个答案组件中删除类红色,然后应用于选定的一个
changeBackgroundColor(ans1,ans2,ans3,ans4, clicked) {
ans1.classList.remove('red');
ans2.classList.remove('red');
ans3.classList.remove('red');
ans4.classList.remove('red');
clicked.classList.add('red');
}
推荐阅读
- ios - 有没有办法在应用程序在 ios 中处于后台时查找用户是否正在打字?
- python - 在熊猫数据框中打开文件内容时如何维护二进制数值
- python - 查找序列并删除以前的条目
- flutter - 单击按钮时在同一屏幕上显示 TextField 值
- ios - 如何在颤振项目中使用 Firebase 实现电话身份验证?
- xamarin - 如果应用程序被杀死,UIBGTaskScheduler 会工作吗?
- python - 有没有办法捕获用户未通过身份验证的异常?
- node.js - 错误:当我想在 ejs 文件中显示时,它们发送到客户端后无法设置标题
- csv - tshark 不会将 TCP 碎片组装成大数据包
- c - AIX - XercesC 运行时错误:未找到符号的运行时定义