自定义通用输入组件 - 验证错误未按预期工作

Custom Common Input Component - Validation Errors not working as expected

我正在尝试为 Material Angular 编写一个通用输入组件,因此我不必为每个字段重复 20 行 HTML 代码。但是我在让 mat-error 显示验证消息时遇到问题。

所以这是我在 MyFormComponent:

中的代码
<div class="form-group">

  <mat-form-field appearance="fill" hintLabel="Max 10 characters">
  
    <mat-label> Name Old (works) </mat-label>
    
    <input matInput type="text" formControlName="nameOld" />

    <mat-hint align="end">the/10</mat-hint>

    <mat-error *ngIf=" (formModal.get('nameOld').dirty || formModal.get('nameOld').touched) &&
        formModal.get('nameOld').errors && formModal.get('nameOld').errors['required'] ">
      Name Old is required.
    </mat-error>
      
  </mat-form-field>
  
</div>

现在我已将其移至自定义组件 CommonInputComponent,如下所示:

HTML:

<div class="form-group">
  <mat-form-field appearance="fill" hintLabel="Max 10 characters">
    <mat-label>{{ fieldInfo.label }}</mat-label>
    <input
      matInput
      [type]="fieldInfo.type"
      [placeholder]="fieldInfo.placeholder"
      [value]="value"
      (input)="onChange($event.target.value)"
      (blur)="onTouched()"
    />

    <mat-hint align="end">{{ ngControl.value?.length || 0 }}/10</mat-hint>

    <mat-error
      *ngIf="
        (ngControl.dirty || ngControl.touched) &&
        ngControl.errors &&
        ngControl.errors['required']
      "
      >Name is required.</mat-error
    >
  </mat-form-field>

  <pre>{{ ngControl.errors | json }}</pre>
  <pre>{{ { dirty: ngControl.dirty, touched: ngControl.touched } | json }}</pre>
</div>

然后我尝试在我的表单 MyFormComponent 中使用它作为:

<app-common-input
  formControlName="name"
  [fieldInfo]="{ label: 'name', name: 'name', type: 'text' }"
></app-common-input>

所有绑定似乎都工作正常,属性在父组件和子组件之间更新,但我面临的唯一问题是 mat-error 似乎不像在前面的例子。

我希望在下面的两个字段中显示“需要姓名”。输入为空时两个字段的错误消息。但是我只在第二个字段中看到它(它没有使用我的公共组件)。

我在 StackBlitz 中创建了一个工作示例 (https://stackblitz.com/edit/add-angular-material-yph1vt?file=src/app/app.component.ts)

您的 app-common-input 中的 mat-input 未绑定到任何 FormControl。您通过将 valueonChangeonTouched 事件绑定到 <input> 来解决它,但 none 实际上传递了有关验证和状态的信息FormControl 本身。

mat-errormat-form-field 内部工作的方式需要知道绑定 FormControl 有一些错误要显示。

因为你似乎要找的是一种“pass-through”ControlValueAccessor,你可以只替换这部分:

<input
  matInput
  [type]="fieldInfo.type"
  [placeholder]="fieldInfo.placeholder"
  [value]="value"
  (input)="onChange($event.target.value)"
  (blur)="onTouched()"
/>

有了这个:

<input
  matInput
  [type]="fieldInfo.type"
  [placeholder]="fieldInfo.placeholder"
  [formControl]="ngControl.control"
/>

这意味着您的组件发生的所有事情都将传递给内部 matInput 和 vice-versa。