我正在将 Angular Material 与 Angular 7 一起使用。我有许多反应形式,每个形式都有自己的控制,并且每个形式都更新正在编辑的主要对象的不同属性集合。这些控件各自托管在 Angular Material Stepper 控件的不同步骤中。
每个控件都有一个名为“添加新”的按钮,允许用户向集合中添加新对象,以及一个“编辑”按钮,用于编辑集合中的任何现有项目。每当单击“添加新项”按钮时,我都会创建一个具有默认值(最空)的新项,并将其绑定到控件中的反应式表单。
表单始终允许用户单击“添加到集合”按钮(即,该按钮永远不会被禁用),并且验证错误(如果有)会在此时向用户显示。(如果存在验证错误,则该项目不会添加到集合中。)
一切工作正常,直到我转到步进器控件的另一步骤,然后返回我正在处理的步骤。发生这种情况时,我单击“添加新项”按钮,即使用户没有单击“添加到集合”按钮,我也会立即看到所有必需的验证错误。当我查看控件的值时,我没有看到任何应该显示验证错误的原因,但它们确实如此(空输入周围的红色突出显示)。
这是每当用户单击“添加新”时我运行的代码:
public resetForm(formGroup: FormGroup) {
if (!formGroup)
return;
formGroup.reset();
formGroup.clearValidators();
// see /sf/ask/3375143131/
Object.keys(formGroup.controls).forEach(key => {
if (ignoreControls.indexOf(key) == -1) {
formGroup.get(key).setErrors(null);
formGroup.get(key).markAsPristine();
formGroup.get(key).markAsUntouched();
formGroup.get(key).clearValidators();
formGroup.get(key).updateValueAndValidity();
}
});
Run Code Online (Sandbox Code Playgroud)
当我在 html 中查看单个控件时,我看到了我期望看到的所有内容:
<input _ngcontent-wyd-c14="" class="mat-input-element mat-form-field-autofill-control cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-invalid" formcontrolname="title" matinput="" placeholder="e.g. Customer Service Representative" required="" type="text" ng-reflect-required="" ng-reflect-name="title" ng-reflect-placeholder="e.g. Customer Service Represen" ng-reflect-type="text" id="mat-input-24" aria-invalid="true" aria-required="true">
Run Code Online (Sandbox Code Playgroud)
请注意,该类包含 ng-untouched 和 ng-pristine (以及 ng-invalid)。如果字段是原始且未受影响的,则它不应该显示验证错误。
我怀疑的是,更改为 Stepper 控件上的不同步骤会导致某种形式的表单提交或提交尝试,这就是为什么显示所有错误(form.subscribed == true 或类似的内容)。但我不知道如何重置任何内容以将表单视为全新的。
有人可以帮忙吗?
(注意:我看过很多 SO 文章,建议我需要在表单指令上调用 ResetForm,而不是在 formGroup 上(参见,例如Angular 5 FormGroup Reset does not Reset validators)。但是,当我添加 # formDirective="ngForm" 添加到我的表单标签,然后添加到我的打字稿中:
@ViewChild('formDirective') private formDirective: NgForm;
Run Code Online (Sandbox Code Playgroud)
然后我调用 this.formDirective.resetForm(),这没有什么区别 - 验证错误仍然立即显示。
更新:这是一个 stackblitz,它基本上显示了问题。在第一步中单击“保存并继续”,然后在第二步中单击“添加新项”。表单显示没有验证错误。现在单击步进器的“Intro”步骤,然后单击返回“Experiences”步骤,当您返回到该步骤时,您将看到所有验证都会出现。这是我的实际生产项目中的问题 - 用户应该能够从一个步骤导航到另一步骤而不触发验证。在体验组件中,您可以看到每次调用 intiForm 方法时都尝试重置表单,但您仍然看到错误。为什么?链接: https: //stackblitz.com/edit/angular-w4iunu
我怀疑的是,更改为 Stepper 控件上的不同步骤会导致某种形式的表单提交或提交尝试,这就是为什么显示所有错误(form.subscribed == true 或类似的内容)。
你就在这里。单击“添加新”按钮会导致提交表单,因为默认情况下 HTML 中的任何按钮都具有 type submit。一旦您单击Add New按钮,您的表单就会获得submitted标记。
解决方案应该很简单:
<button mat-raised-button color="primary" (click)="addNew()" type="button"...>Add New</button>
^^^^^^^^^
add this
Run Code Online (Sandbox Code Playgroud)
interacted这里的另一个问题是,Stepper在计算控制的错误状态时会考虑步骤的属性。一旦你从一个步骤移动到另一个步骤,它就变成了true。
您可以通过重置此属性来解决此问题selectionChange:
应用程序组件.html
<mat-horizontal-stepper #diaryStepper ... (selectionChange)="stepIndexChanged(diaryStepper)"
Run Code Online (Sandbox Code Playgroud)
应用程序组件.ts
stepIndexChanged(stepper) {
stepper.steps.toArray().forEach(step => step.interacted = false)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3516 次 |
| 最近记录: |