在新的绑定值上重置 mat radio 组状态
Resetting mat radio group state on new bound value
我正在构建一种问答应用程序。我们有一堆问题,用户应该能够在屏幕上始终只有一个问题的情况下一一回答。
问题之间的更改是通过传递给问题组件的路由参数进行路由来完成的。
在组件模板中,我有一个 mat radio 组来显示不同的答案选项(总是值“1”、“2”和“3”)。
当我现在回答一个问题并转到下一个问题时,垫子单选按钮组保持上一个问题答案的状态。我确实想在这里重置状态。所以下一个问题还没有回答(没有选择单选按钮,也没有 none 重点)。
我正在尝试重置单选按钮更改处理程序中的选中状态,但这似乎是一个 hacky 解决方法,而且效果不佳(我无法再次选中相同的答案 -> 导致没有更改事件)。
有没有人知道如何正确实施该用例?
约束条件
- 给定路线的当前问题是从可观察的外观中提取的。这应该保持原样。 facade 后面有一个 ngrx store,它处理所有状态管理逻辑。
- 必须通过外观上的方法调用来保存问题答案。
我很乐意提供任何提示和技巧
这是一个 stackblitz,它大致显示了问题:Stackblitz link
这里发生了一些事情,我将按文件拆分它们。
组件
最重要的是question$
不需要是BehaviorSubject
,可以直接是{ question: string, answer: string }
的变量。如果你想变得花哨,你可以为它定义一个类型:
type Question = {
question: string;
answer: string;
};
所以question$
变成:
public question: Question;
进行此更改后,路由订阅如下所示:
this.subscription = this.activatedRoute.paramMap.pipe(
// ...Maps and Filter all the same...
).subscribe((questionNumber) => {
const question = this.allQuestions[questionNumber - 1];
const answer = this.answers[question];
this.question = { question, answer };
});
(提示:tap
在这里有点多余,为了简单起见,我将其逻辑移到了 subscribe
中,它的行为方式完全相同)
对于此表单中的 question
,要更新它,我们只需更新值,Angular 将选择该更改并相应地更新模板。这最终也简化了模板。
模板
question
只是一个字段,*ngIf
就变成了 *ngIf="question"
。
模板最大的变化是数据绑定语法。 mat-radio-group
是一个表单元素,Angular 将表单值绑定到组件字段的方式是 ngModel
。具体来说,您想将它与“盒子里的香蕉”[( )]
Two-way Binding 语法一起使用,这意味着模板中的更改将更新组件值,反之亦然。
所以模板最终看起来像这样:
<ng-container *ngIf="question">
<div>{{ question.question }}</div>
<mat-radio-group [(ngModel)]="question.answer"> <!-- Magic happens here -->
<mat-radio-button value="1">1</mat-radio-button>
<mat-radio-button value="2">2</mat-radio-button>
<mat-radio-button value="3">3</mat-radio-button>
</mat-radio-group>
<button (click)="goNext()">Go next</button>
</ng-container>
value
字段应该在 mat-radio-button
上。这是选择其中一个选项时实际分配的数据 question.answer
。
就是这样!这里是 the StackBlitz 添加了一些额外的日志记录以显示 answers
.
的状态
更新
考虑到更新问题的约束,将 question$
保持为 Observable,模板应如下所示:
<ng-container *ngIf="question$ | async as question">
<div>{{ question.question }}</div>
<mat-radio-group [(ngModel)]="question.answer">
<mat-radio-button value="1">1</mat-radio-button>
<mat-radio-button value="2">2</mat-radio-button>
<mat-radio-button value="3">3</mat-radio-button>
</mat-radio-group>
<button (click)="goNext(question)">Go next</button>
</ng-container>
使用此方法,可以在 goNext()
.
内部进行外观方法调用以保存答案
已更新 StackBlitz here。
我正在构建一种问答应用程序。我们有一堆问题,用户应该能够在屏幕上始终只有一个问题的情况下一一回答。 问题之间的更改是通过传递给问题组件的路由参数进行路由来完成的。 在组件模板中,我有一个 mat radio 组来显示不同的答案选项(总是值“1”、“2”和“3”)。
当我现在回答一个问题并转到下一个问题时,垫子单选按钮组保持上一个问题答案的状态。我确实想在这里重置状态。所以下一个问题还没有回答(没有选择单选按钮,也没有 none 重点)。 我正在尝试重置单选按钮更改处理程序中的选中状态,但这似乎是一个 hacky 解决方法,而且效果不佳(我无法再次选中相同的答案 -> 导致没有更改事件)。
有没有人知道如何正确实施该用例?
约束条件
- 给定路线的当前问题是从可观察的外观中提取的。这应该保持原样。 facade 后面有一个 ngrx store,它处理所有状态管理逻辑。
- 必须通过外观上的方法调用来保存问题答案。
我很乐意提供任何提示和技巧 这是一个 stackblitz,它大致显示了问题:Stackblitz link
这里发生了一些事情,我将按文件拆分它们。
组件
最重要的是question$
不需要是BehaviorSubject
,可以直接是{ question: string, answer: string }
的变量。如果你想变得花哨,你可以为它定义一个类型:
type Question = {
question: string;
answer: string;
};
所以question$
变成:
public question: Question;
进行此更改后,路由订阅如下所示:
this.subscription = this.activatedRoute.paramMap.pipe(
// ...Maps and Filter all the same...
).subscribe((questionNumber) => {
const question = this.allQuestions[questionNumber - 1];
const answer = this.answers[question];
this.question = { question, answer };
});
(提示:tap
在这里有点多余,为了简单起见,我将其逻辑移到了 subscribe
中,它的行为方式完全相同)
对于此表单中的 question
,要更新它,我们只需更新值,Angular 将选择该更改并相应地更新模板。这最终也简化了模板。
模板
question
只是一个字段,*ngIf
就变成了 *ngIf="question"
。
模板最大的变化是数据绑定语法。 mat-radio-group
是一个表单元素,Angular 将表单值绑定到组件字段的方式是 ngModel
。具体来说,您想将它与“盒子里的香蕉”[( )]
Two-way Binding 语法一起使用,这意味着模板中的更改将更新组件值,反之亦然。
所以模板最终看起来像这样:
<ng-container *ngIf="question">
<div>{{ question.question }}</div>
<mat-radio-group [(ngModel)]="question.answer"> <!-- Magic happens here -->
<mat-radio-button value="1">1</mat-radio-button>
<mat-radio-button value="2">2</mat-radio-button>
<mat-radio-button value="3">3</mat-radio-button>
</mat-radio-group>
<button (click)="goNext()">Go next</button>
</ng-container>
value
字段应该在 mat-radio-button
上。这是选择其中一个选项时实际分配的数据 question.answer
。
就是这样!这里是 the StackBlitz 添加了一些额外的日志记录以显示 answers
.
更新
考虑到更新问题的约束,将 question$
保持为 Observable,模板应如下所示:
<ng-container *ngIf="question$ | async as question">
<div>{{ question.question }}</div>
<mat-radio-group [(ngModel)]="question.answer">
<mat-radio-button value="1">1</mat-radio-button>
<mat-radio-button value="2">2</mat-radio-button>
<mat-radio-button value="3">3</mat-radio-button>
</mat-radio-group>
<button (click)="goNext(question)">Go next</button>
</ng-container>
使用此方法,可以在 goNext()
.
已更新 StackBlitz here。