简体   繁体   English

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

[英]Angular material dialog pre-populated input field does not validate

I have a mat-dialog that opens from an edit button in a (mat-)table.我有一个垫对话框,它从(垫)表中的编辑按钮打开。 When the dialog opens it gets passed data to populate some input fields.当对话框打开时,它会传递数据以填充一些输入字段。
One of those inputs has validation with the rule that it cannot be empty.其中一个输入通过不能为空的规则进行验证。

My problem is that the input element that receives an auto-populated value is not recognized by Angular as having a value at all (it has a 'value' in the web-inspector and on the screen).我的问题是,接收自动填充值的输入元素根本没有被 Angular 识别为具有值(它在网络检查器和屏幕上都有一个“值”)。

This means that until the user edits the field either by deleting and reentering a character or typing something new, the 'save' button remains greyed-out.这意味着,除非用户通过删除并重新输入字符或键入新内容来编辑该字段,否则“保存”按钮将保持灰色。 Not al fields need to be edited, if they receive a value it is a valid one.并非所有字段都需要编辑,如果它们收到一个值,它就是一个有效的值。

So how can I get the validation to recognize that the input field is not empty but also that it does have a value ?那么我怎样才能得到验证以识别输入字段不为空而且它确实有一个值 (The reason I can't just remove the validation, it has to have a value, ie != '' ). (我不能只删除验证的原因,它必须有一个值,即!= '' )。

So unless the user input is empty to start with or the user deletes the input, the validation should pass.因此,除非用户输入一开始为空或用户删除输入,否则验证应该通过。 Or to say it another way, if the input receives a value when the dialog opens, and the user leaves it well alone, the validation should pass.或者换一种说法,如果输入在对话框打开时收到一个值,而用户将其置之不理,则验证应该通过。

A side effect of the auto-populated values not being recognized is that if a number is unchanged then it gets posted as null to the backend.无法识别自动填充值的副作用是,如果数字未更改,则它会作为 null 发布到后端。 So when the data is refreshed in the view, a number that was 30 and not edited by the user is now 0. This, because the form is displaying the auto-populated data, but somehow angular isn't "seeing" it.所以当数据在视图中刷新时,一个 30 且未被用户编辑的数字现在是 0。这是因为表单正在显示自动填充的数据,但不知何故 angular 没有“看到”它。

simple input:简单输入:

  <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>

Not sure what to show from the component.ts files here(?!)不确定要从 component.ts 文件中显示什么(?!)
Using dialogRef.componentInstance = foo.bar;使用dialogRef.componentInstance = foo.bar; in the parent component, the dialog gets it's correct values in the input fields and IF the user deletes and then retypes a value, the correct value is sent back via the API.在父组件中,对话框在输入字段中获取正确的值,如果用户删除然后重新键入一个值,正确的值将通过 API 发回。

The issue is that angular can't 'see' the input.问题是 angular 无法“看到”输入。
Tried a lot of different stuff, including every other answer on SO/here.尝试了很多不同的东西,包括 SO/here 上的所有其他答案。
Sorry long text and little code, but there isn't anything to show how angular doesn't recognize that the input field holds a value.对不起长文本和很少的代码,但没有什么可以炫耀如何角不识别输入字段包含一个值。

I searched long and hard for an answer to this problem, and I think I have the "correct" way to it (one of them at least).我长期努力地寻找这个问题的答案,我认为我有“正确”的方法(至少是其中之一)。 So I'll post it here:所以我会把它贴在这里:

First, I changed my form to use 'formGroup' in the form element like so:首先,我将表单更改为在表单元素中使用“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 ...]

Notice that I had to remove [(ngModel)]="someVal" from all the form field elements.请注意,我必须从所有表单字段元素中删除[(ngModel)]="someVal" Angular throws a wobbly if you try to use them with formGroup.如果您尝试将它们与 formGroup 一起使用,Angular 会抛出一个不稳定的问题。

Now add the element attribute formControlName="name" you see in the code above.现在添加您在上面的代码中看到的元素属性formControlName="name"

I then had to add to app.module.ts ReactiveFormsModule:然后我不得不添加到app.module.ts ReactiveFormsModule:

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

and also add this to the imports array of that same file:并将其添加到同一文件的导入数组中:

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

In the component.ts file I set up the [formGroup]="patchForm" according to the documentation here https://angular.io/api/forms/FormGroup#setvaluecomponent.ts文件中,我根据此处的文档设置了[formGroup]="patchForm" https://angular.io/api/forms/FormGroup#setvalue
I have 3 fields in my dialog:我的对话框中有 3 个字段:

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

So, the formControl expects an object correspondng to the form.因此,formControl 需要一个与表单对应的对象。 In my onInit function i have a call to the API to get the data I want to populate the form with, and so inside that subscriber I am using patchValue() method from Angular to set the values:在我的onInit函数中,我调用了 API 来获取我想要填充表单的数据,因此在该订阅者中,我使用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']
   });
});

That seemed to work.那似乎奏效了。 Then I had to set the valules of the object I was returning to the API/database in my return object to point to the correct values, so when the user clicks the button "save" it calls a 'confirmPut' function that contains the object data to be sent, like so:然后,我必须在返回对象中设置返回到 API/数据库的对象的值以指向正确的值,因此当用户单击“保存”按钮时,它会调用包含该对象的“confirmPut”函数要发送的数据,如下所示:

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

which in turn calls the function that does the PUT to the API.它反过来调用对 API 执行 PUT 的函数。

I think that was it, the form validates against empty strings and missing values as expected.我认为就是这样,表单按预期针对空字符串和缺失值进行验证。

If I have missed anything and anyone ever reads this, let me know... :)如果我错过了什么并且有人读过这篇文章,请告诉我... :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM