【问题标题】:How can I toggle between mat-checkbox or mat-radio-button in Angular reactive form?如何在 Angular 反应形式的 mat-checkbox 或 mat-radio-button 之间切换?
【发布时间】:2020-04-30 17:39:54
【问题描述】:

我正在创建一个测验应用程序,需要在 mat-checkbox 或 mat-radio-button 之间切换,具体取决于问题是否有一个或多个答案。问题 #1 是单选答案问题,使用 mat-radio-button 显示,而问题 #2 是多选问题,但也使用 mat-radio-button 而不是 mat-checkbox 显示。

这是我的模板的样子:

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

在我的 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;
    }
  }
}

不需要 shuffledAnswers,问题类型应该从 assets/quiz.ts 文件中推断出来(不需要硬编码问题类型),答案应该是数字,而不是字符串

在我的 QuizService 中:

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

【问题讨论】:

  • 我看不到你的完整代码,所以我猜。也许问题是您只在ngOnInit 内检查multipleAnswer 一次。您是否尝试在ngOnChanges 中检查它?
  • 是的,我将它添加到 ngOnChanges,但它似乎不起作用。
  • 我添加了上面显示的新 ngOnChanges 代码,但在控制台中出现此错误:core.js:6237 ERROR NullInjectorError: R3InjectorError(QuizRoutingModule)[FormBuilder -> FormBuilder -> FormBuilder -> FormBuilder]: NullInjectorError: 没有 FormBuilder 的提供者!
  • 抱歉,我不能说太多。也许如果您可以将相关部分分享为堆栈闪电战,我们可以对其进行检查。
  • 请看我的stackblitz:stackblitz.com/edit/angular-9-quiz-app

标签: angular angular-material


【解决方案1】:

有几个问题。首先,仅在 ngOnInit 内部调用 multipleAnswer 会在开始时仅设置此布尔变量一次,它应该在 ngOnChanges 内部。

但这不是这里唯一的问题,主要问题在于您的QuizService。在这里,您使用this.quizService.getQuestionType(); 方法设置multipleAnswer true 或false,但在QuizService 的getQuestionType() 方法中,您正在检查this.correctAnswers 是否已设置并且元素长度为1,但this.correctAnswers 在您调用它时始终为空。

另一个问题是你的ngOnChanges 你有switch (this.question.type) 这里this.question 似乎永远是未定义的。

像下面这样编辑您的代码,并在每次出现问题时检查控制台输出。

添加一个从问题中获取correctAnswers 的新方法。

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

并像下面这样编辑 ngOnChanges 的开头,我还添加了一个控制台输出,以便您可以从上面的新方法中看到数据。

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

我无法修改所有代码,因为您的代码背后有自己的逻辑,但我更新了答案,以便在“ngOnChanges”中正确设置与此问题相关的变量。

【讨论】:

  • 感谢您的帮助。我还是有点卡住了。我通过添加 this.multipleAnswer = this.correctAnswers.length > 1 更新了我的堆栈闪电战?真假;到 ngOnChanges(而不是使用 quizservice),并在 setSelected 函数中添加了正确答案的推送。似乎有时它工作正常,有时却不行。第二个问题应该使用复选框(并且应该只选择第一个和第二个问题作为正确答案)。
  • 更新了答案,还分叉了你的 stackblitz 并应用了解决方案。 stackblitz.com/edit/angular-9-quiz-app-phgyaq
  • 谢谢,但现在我注意到现在所有答案都选择正确,而第二个问题中,当回答正确时,分数没有增加。
  • 好吧,正如我在答案中所说,我无法修改所有代码,因为您的代码背后有自己的逻辑。但是,您应该根据我们所做的更改来调整代码的其他部分,即当问题更改时,您会计算 ngOnChanges 中的所有内容。例如,当单选按钮更改时触发了 setSelected 方法,仍然有一些来自 quizService 的计算,请检查它们是否按预期服务。
  • 是的,我能够轻松修复错误,这是因为 mat-radio-group 和 mat-checkbox-group 被禁用。 I could use some help with the mat-checkbox question (Question 2) doesn't seem to be incrementing when the correct answers are chosen.
猜你喜欢
  • 2019-05-22
  • 2018-07-31
  • 2019-05-30
  • 2021-01-01
  • 2020-12-01
  • 2021-07-26
  • 1970-01-01
  • 2019-08-24
  • 2019-02-06
相关资源
最近更新 更多