首页 > 解决方案 > 如何在角度 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>

标签: angularfrontend

解决方案


创建一个类 -

 .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');
}

推荐阅读