【问题标题】:how to display background-color only on selected option in quiz如何仅在测验中的选定选项上显示背景颜色
【发布时间】:2021-01-19 13:32:00
【问题描述】:

在我的 Angular quiz app 中,我的两个问题组件(MultipleAnswerComponent)都有相同的逻辑:option.selected && option.correctoption.selected && !option.correct > 和 SingleAnswerComponent) 模板,所以我移出了逻辑并在 QuizService 中添加了两个变量以共享/减少重复代码:

setOptions(optionSelected: boolean, optionCorrect: boolean): void {
  this.isCorrectOption = optionSelected && optionCorrect;
  this.isIncorrectOption = optionSelected && !optionCorrect;
}

我还用类绑定中的变量替换了逻辑,如下所示:[class.is-correct]="isCorrectOption"[class.is-incorrect]="isIncorrectOption",但是所有选项都变红了,所以我更改了 mat-checkbox/ 上的背景颜色mat-radio-button 到 $light-gray !important 现在它是灰色的。当我单击某个选项时,绿色或红色背景未按预期显示。

编辑: 我在 QuizService 中获得了 isCorrectOptionisIncorrectOption 的正确值,并将这些值传递回组件。然而现在所有的选项在点击一个选项时显示为绿色/红色;我只需要 selected 选项 来获得背景颜色。不确定 isCorrectOptionisIncorrectOption 是否正确绑定到类绑定,或者我使用的逻辑是否不正确...

我尝试按照以下答案中的建议进行操作,但出现错误:无法读取未定义的“已选择”。我目前的解决方案非常接近解决方案,但我仍然需要一些额外的帮助才能使个人突出显示正常工作。请你看看我的 StackBlitz 并帮我解决这个问题。谢谢。

MultipleAnswerComponent/SingleAnswerComponent 模板中:

<div class="options" *ngFor="let option of currentQuestion.options; index as i">
  <div *ngIf="multipleAnswer" or *ngIf="!multipleAnswer">
    <mat-checkbox or <mat-radio-button
      (change)="setSelected(i)"
      [class.is-correct]="isCorrectOption"
      [class.is-incorrect]="isIncorrectOption">

在 MultipleAnswer/SingleAnswer TypeScript 文件中:

setSelected(optionIndex: number): void {
  this.quizStarted = true;
  this.isCorrectAnswerSelected = this.isCorrect(this.currentQuestion.options[optionIndex].correct, optionIndex);
  this.answer.emit(optionIndex);

  if (this.correctAnswers.length === 1) {
    this.currentQuestion.options.forEach((option: Option) => option.selected = false);
  }
  this.currentQuestion.options[optionIndex].selected = true;

  if (
    optionIndex >= 0 &&
    this.currentQuestion &&
    this.currentQuestion.options &&
    this.currentQuestion.options[optionIndex]["correct"]
  ) {
    optionIndex = null;
    this.optionCorrect = true;
    this.timerService.stopTimer();
    this.quizService.correctSound.play();   
  } else {
    this.optionCorrect = false;
    this.quizService.incorrectSound.play();
  }

  this.quizService.setOptions(true, this.optionCorrect);
  this.isCorrectOption = this.quizService.isCorrectOption;
  this.isIncorrectOption = this.quizService.isIncorrectOption;
  this.alreadyAnswered = true;
}

【问题讨论】:

  • 请使用--background-color: $light-gray !important;
  • 可能是根变量的颜色为红色,这就是它没有改变的原因。我不明白你的评论。
  • 选项的背景颜色应根据每个选项的正确/错误从灰色变为绿色或灰色变为红色。我不认为逻辑正在执行......
  • 我想出了如何传递值。在 MultipleAnswerComponent 和 SingleAnswerComponent 中添加了 console.log 并获得 optionSelected: 'true' 和 optionCorrect: 'true' 正确答案值和 optionSelected: 'true' 和 optionCorrect: 'undefined' 错误答案,并且得到相同的值从测验服务。接近解决这个问题,仍然需要帮助来改变背景颜色。请看我的 Stackblitz。

标签: css angular css-selectors logic ng-class


【解决方案1】:

您的问题是当您在测验服务中保存所选状态时。

当您在测验中选择一个项目并调用setOptions(optionSelected: boolean, optionCorrect: boolean) 时,optionSelected 的值是 true(因为当前项目)。问题是测验服务isCorrectOptionisIncorrectOption 的值使用optionSelected 的相同实例,因此所有项目都是如此。

怎么办? 好吧,不要为此使用测验服务,而是在每个 Option 实例中使用保存的选定状态。

在打字稿中你已经这样做了:

this.optionSelected = this.currentQuestion.options[optionIndex];
this.optionSelected.selected = true;
this.optionSelected.correct = false;

所以在 html 中使用这些值:

[class.is-correct]="option.selected && option.correct"

(或为此创建一个函数)

当然,您可以重构它以使用解决该问题的测验服务。

【讨论】:

  • 我更新了我的 TS 文件,如上面在 stackblitz 中所示的多答案问题。它似乎不起作用,不确定在类绑定中替换什么。我希望我可以像以前使用 isCorrectOption 和 isIncorrectOption 一样将逻辑简化为单个变量。
  • @adrisons 是正确的,解决方案正在运行,如您在此处看到的那样:stackblitz.com/edit/… 替代方法是为每个选项设置类名并绑定到该选项:stackblitz.com/edit/…
  • 是的,第二个 Stackblitz 正是我想要的。非常感谢!我真的很感激。
【解决方案2】:

isCorrectOptionisIncorrectOption 都是(非空)字符串,因此评估为真。

把你的代码改成这样就可以了:

isCorrectOption = option.selected && option.correct;
isIncorrectOption = option.selected && !option.correct;

【讨论】:

  • 我创建了 this.option = this.currentQuestion.options[optionIndex];并将其传递给 QuizService,但收到错误消息:“错误:未捕获(承诺中):TypeError:无法读取未定义的属性'selected'。”请你看看我的 Stackblitz。
  • 我想出了如何传递值。在 MultipleAnswerComponent 和 SingleAnswerComponent 中添加了 console.log 并获得 optionSelected: 'true' 和 optionCorrect: 'true' 正确答案和 optionSelected: 'true' 和 optionCorrect: 'undefined' 错误答案的值,并且得到相同的值从测验服务。接近解决这个问题,仍然需要帮助来改变背景颜色。请看我的 Stackblitz。
  • QuizService 中的 isCorrectOptions 和 isIncorrectOptions 以及通过 DI 获得的值未定义。
  • 好的,我对 optionSelected 和 optionCorrect 的值进行了硬编码,得到了正确的真/假值,但 isCorrectOption 和 isIncorrectOption 仍未定义
  • 我得到了 isCorrectOption 和 isIncorrectOption 的真实值,因为我将 optionSelected 和 optionCorrect 初始化为 true,但是当我单击选项时,颜色不会改变。当我点击一个选项时,这些值不会改变。
【解决方案3】:

如果您只需要突出显示选定的选项,则无需将is-correctis-incorrect 类应用于单选按钮。

相反,您可以添加新类 selected 并像这样使用它:

<mat-checkbox (change)="setSelected(i)" [class.selected]="option.selected">
  ...
</mat-checkbox>

<mat-radio-button (change)="setSelected(i)" [class.selected]="option.selected">
  ...
</mat-radio-button>

将 .selected 类添加到相应的 css 文件中:

.selected {
  background: lightblue;
}

查看更新后的stackblitz

【讨论】:

  • 实际上我确实需要这些课程,因为我需要用绿色背景突出正确答案,用红色背景突出错误答案。我使用的是 isCorrectOption 和 isIncorrectOption 之类的变量,因为我在 MultipleAnswerComponent 和 SingleAnswerComponent 中都有相同的逻辑,并希望将逻辑简化为单个变量。
  • @mjbk123 但我相信您的绑定完全错误,甚至没有考虑当前选项。那么你到底需要什么样的突出显示呢?仅对选定的正确/不正确?
  • 是的,我需要单独的正确/错误答案 - 正确答案应突出显示为绿色,错误答案应突出显示为红色。并且应该简化逻辑: [class.is-correct] = "isCorrectOption", not option.selected && option.correct
  • @mjbk123 但如果我进行任何更改,它看起来就像您在重构之前所做的那样。我不明白你说的避免重复是什么意思。您仍然需要自行存储 isSelected 和 isCorrect 选项。
  • 模板中的逻辑要尽量简单。我将代码移动到服务中以共享重复的代码,因为它在两个组件文件中是相同的。组件中的代码使用依赖注入将值从服务发送回组件。这应该是可能的。
【解决方案4】:

检查下面要更正的代码行

multiple-answer.component.html

来自:

<mat-checkbox (change)="setSelected(i)" [class]="option.className">

到:

<mat-checkbox (change)="setSelected(i)" [class.is-correct]="option.selected && option.correct" [class.is-incorrect]="option.selected && !option.correct">

【讨论】:

    猜你喜欢
    • 2020-01-17
    • 2014-05-07
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多