角材料对话框预填充的输入字段未验证

时间:2018-09-11 20:39:03

标签: javascript angular validation angular-material angular6

我有一个Mat对话框,可以通过(mat-)表中的编辑按钮打开。 对话框打开时,它将获取传递的数据以填充一些输入字段。
这些输入之一具有不能为空的规则的验证。

我的问题是,接收自动填充的值的输入元素根本无法被Angular识别为具有值(它在Web检查器和屏幕上都具有“值”)。

这意味着在用户通过删除和重新输入字符或键入新内容来编辑字段之前,“保存”按钮保持为灰色。不是所有字段都需要编辑,如果它们接收到的值是有效的。

那么我如何获得验证以识别输入字段不为空但还具有值? (我不能仅仅删除验证的原因,它必须具有一个值,即!= '')。

因此,除非用户输入开头是空的或者用户删除了输入,否则验证应该通过。换句话说,如果在对话框打开时输入接收到一个值,并且用户将其搁置一旁,则验证应该通过。

无法识别自动填充的值的副作用是,如果数字不变,则该数字将作为null发布到后端。因此,当在视图中刷新数据时,原来为30且用户未编辑的数字现在为0。这是因为表单显示的是自动填充的数据,但是在某种程度上,角度显示并不能“看到”它。

简单输入:

  <div class="form">
    <mat-form-field>
      <input matInput #input
             class="form-control"
             placeholder="Name"
             [(ngModel)]="data.name"
             name="name"
             selected="data.name"
             required
             [value]="this.getFunc?.name"
      >
      <mat-error *ngIf="data.name == ''">{{getErrorMessage()}}</mat-error>
    </mat-form-field>
  </div>

不确定在此处显示来自component.ts文件的内容(?!)
在父组件中使用dialogRef.componentInstance = foo.bar;,对话框会在输入字段中获取正确的值,如果用户删除然后重新输入值,则该正确的值会通过API发送回去。

问题在于,角度无法“看到”输入。
尝试了很多不同的东西,包括关于SO / here的所有其他答案。
抱歉,较长的文本和很少的代码,但是没有任何东西可以显示如何 angular无法识别输入字段包含值。

1 个答案:

答案 0 :(得分:0)

我花了很长时间寻找这个问题的答案,我认为我有“正确”的解决方法(至少是其中之一)。因此,我将其发布在这里:

首先,我将表单更改为在form元素中使用“ formGroup”,如下所示:

<form class="mat-dialog-content" (ngSubmit)="submit()" #formControl="ngForm" [formGroup]="patchForm">
      <div class="form">
        <mat-form-field>
          <input matInput #input
                 class="form-control"
                 placeholder="name"
                 name="name"
                 formControlName="name"
                 id="name"
                 selected="data.name"
                 required
          >
          <mat-error *ngIf="data.name== ''">{{getErrorMessage()}}</mat-error>
        </mat-form-field>
      </div>
      [... repeat div class="form" blocks for other inputs/dropdowns etc ...]

请注意,我必须从所有表单字段元素中删除[(ngModel)]="someVal"。如果您尝试将它们与formGroup一起使用,Angular会产生抖动。

现在添加您在上面的代码中看到的元素属性formControlName="name"

然后我必须添加到 app.module.ts ReactiveFormsModule:

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

,并将其添加到同一文件的imports数组中:

 imports: [
    BrowserModule,
    ...
    FormsModule,
    ReactiveFormsModule
  ],  

component.ts 文件中,根据https://angular.io/api/forms/FormGroup#setvalue此处的文档设置了[formGroup]="patchForm"
对话框中有3个字段:

  patchForm = new FormGroup({
    age: new FormControl(),
    name: new FormControl(),
    numberLegs: new FormControl()
  });

因此,formControl期望与该表单相对应的对象。在我的 onInit 函数中,我调用了API以获取要填充表单的数据,因此在该订阅者内部,我使用Angular的patchValue()方法来设置值:

this.projectService.getProjectFunction(this.projId, this.rowId).subscribe(x=> { 
  this.fetchedProjFunc = x;
  // patchFrom expects an object matching to the formgroup, field by field.
  this.patchForm.patchValue({
    age: this.fetchedProjFunc['age'],
    name: this.fetchedProjFunc['name'],
    numberLegs: this.fetchedProjFunc['numberLegs']
   });
});

那似乎行得通。然后,我必须在返回对象中设置要返回到API /数据库的对象的值,以指向正确的值,因此,当用户单击“保存”按钮时,它将调用包含该对象的“ confirmPut”函数要发送的数据,如下所示:

 public confirmPut(): void {
    this.projectFunction = {
        ...
        name: this.patchForm.value['name'],
        ...

依次调用将PUT执行到API的函数。

我认为就是这样,该表单可以针对空字符串和缺少的值进行验证,是否如预期的那样。

如果我错过了任何东西,而且任何人都读过,请告诉我...:)