自定义通用输入组件 - 验证错误未按预期工作
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
。您通过将 value
、onChange
和 onTouched
事件绑定到 <input>
来解决它,但 none 实际上传递了有关验证和状态的信息FormControl
本身。
而 mat-error
在 mat-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。
我正在尝试为 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
。您通过将 value
、onChange
和 onTouched
事件绑定到 <input>
来解决它,但 none 实际上传递了有关验证和状态的信息FormControl
本身。
而 mat-error
在 mat-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。