简体   繁体   English

如何在 Angular 反应形式中的 mat-checkbox 或 mat-radio-button 之间切换?

[英]How can I toggle between mat-checkbox or mat-radio-button in Angular reactive form?

I'm creating a quiz app and need to toggle between mat-checkbox or mat-radio-button, depending on whether the question has one or more answers.我正在创建一个测验应用程序,需要在 mat-checkbox 或 mat-radio-button 之间切换,具体取决于问题是否有一个或多个答案。 Question #1 is a single choice answer question and shows with mat-radio-button whereas Question #2 is a multiple answer question but is also displaying with mat-radio-button instead of mat-checkbox.问题 #1 是单选答案问题,使用 mat-radio-button 显示,而问题 #2 是多选问题,但也使用 mat-radio-button 而不是 mat-checkbox 显示。

This is how my template looks like:这是我的模板的样子:

<form [formGroup]="formGroup">
    <ol *ngIf="multipleAnswer === false">
        // using mat-radio-buttons here 
    </ol>
    <ol *ngIf="multipleAnswer === true">
        // using mat-checkboxes here
    </ol>
</form>

and in my ts file the logic looks like:在我的 ts 文件中,逻辑如下所示:

multipleAnswer: boolean;

ngOnInit() {
  this.multipleAnswer = this.quizService.getQuestionType();
}

ngOnChanges(changes: SimpleChanges) {
  if (changes.question) {
    switch (this.question.type) {
      case 'SINGLE_CHOICE':
        this.formGroup = new FormGroup({
          answer: new FormControl([null, Validators.required])
        });
        break;
      case 'MULTIPLE_CHOICE':
        const multipleChoiceValidator = (control: AbstractControl) =>
          control.value.reduce(
            (valid: boolean, currentValue: boolean) => valid || currentValue
            , false
          ) ? null : {answers: 'At least one answer needs to be checked!'};
        this.formGroup = new FormGroup({
          answers: this.formBuilder.array(this.question.shuffledAnswers
              .map((answer: string) => this.formBuilder.control(false)),
            multipleChoiceValidator
          ),
        });
        break;
    }
  }
}

don't need shuffledAnswers, question type should be inferred from the assets/quiz.ts file (shouldn't need to hard code the question type), and answers should be numbers, not strings不需要 shuffledAnswers,问题类型应该从 assets/quiz.ts 文件中推断出来(不需要硬编码问题类型),答案应该是数字,而不是字符串

in my QuizService:在我的测验服务中:

getQuestionType(): boolean {
  return (this.correctAnswers && this.correctAnswers.length === 1);
}

There are several problems.有几个问题。 First, calling multipleAnswer only inside ngOnInit sets this boolean variable only once at begining, it should be inside ngOnChanges .首先,仅在ngOnInit内部调用multipleAnswer只会在开始时设置此 boolean 变量一次,它应该在ngOnChanges内部。

But it's not the only issue here, the main problem is in your QuizService .但这不是这里唯一的问题,主要问题在于您的QuizService Here you use this.quizService.getQuestionType();这里你使用this.quizService.getQuestionType(); method to set multipleAnswer true or false but inside your getQuestionType() method of QuizService you are checking this.correctAnswers if set and has element length of 1 but this.correctAnswers is always empty when you call it.设置multipleAnswer true 或 false 的方法,但是在 QuizService 的getQuestionType()方法中,您正在检查this.correctAnswers是否已设置并且元素长度为 1 但this.correctAnswers在您调用它时始终为空。

Another problem is in your ngOnChanges you have switch (this.question.type) here this.question seems to be undefined evertime.另一个问题是在你的ngOnChanges中你有switch (this.question.type)这里this.question似乎永远是未定义的。

Edit your code like below and check console outputs everytime a question appears.像下面这样编辑您的代码,并在每次出现问题时检查控制台输出。

Add a new method the get correctAnswers from a question.添加一个从问题中获取correctAnswers的新方法。

getCorrectAnswers(question:QuizQuestion){
   return question.options.filter((item)=> item.correct);
}

And edit begining of ngOnChanges like below, i also added a console output so you can see the data from the new method above.并像下面这样编辑 ngOnChanges 的开头,我还添加了一个控制台 output 以便您可以从上面的新方法中看到数据。

ngOnChanges(changes: SimpleChanges) {   
   if (changes.question && changes.question.currentValue !== changes.question.firstChange){
     this.currentQuestion = changes.question.currentValue;
     this.correctAnswers = this.getCorrectAnswers(this.currentQuestion);
     this.multipleAnswer = this.correctAnswers.length > 1 ? true : false;
     console.log('correct ans: ', this.correctAnswers);
     ...

I can't modify all of the code since you have your own logic behind your code, but i updated the answer so that variables related to this problem set correctly inside 'ngOnChanges`.我无法修改所有代码,因为您的代码背后有自己的逻辑,但我更新了答案,以便与此问题相关的变量在“ngOnChanges”中正确设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM