我想使用mat-errors在我的Angular 5 SPA中渲染服务器端错误。
这是我到目前为止所做的,并且有效。
<mat-form-field class="col-6">
<input matInput formControlName="firstName">
<mat-error [hidden]="!form.controls.firstName.hasError('required')">This field is required and cannot be empty</mat-error>
<mat-error [hidden]="!form.controls.firstName.hasError('other')">Some other error</mat-error>
</mat-form-field>
表单的每个字段看起来都很相似。输入字段和下面的许多mat-error标记。单个输入字段附加了大量重复代码。此外,添加新的错误消息会导致在需要它的每个字段中添加它。 我认为这是一个很好的空间来引入管理错误消息的组件,并注入表单控件它决定显示哪个错误(我希望所有字段都有常见的错误消息)。
所以我想这样做
<mat-form-field class="col-6">
<input matInput formControlName="firstName">
<app-mat-errors [field]="form.controls.firstName"></app-map-errors>
</mat-form-field>
并在app-mat-errors
组件模板中包含我们过去在每个字段中拥有的所有mat-error
代码
<mat-error [hidden]="!field.hasError('required')">This field is required and cannot be empty</mat-error>
<mat-error [hidden]="!field.hasError('other')">Some other error</mat-error>
etc....
使用这种方法我遇到了正确渲染组件的问题。
当放入<app-mat-errors>
时,<mat-error>
标记嵌入app-mat-errors
标记并且无法正确显示(即使没有错误,它们也不会始终显示和显示)
有什么方法角度可以渲染组件没有父标签?或者您有任何想法如何使其正常工作?提前谢谢。
答案 0 :(得分:10)
<mat-error>
元素必须是<mat-form-field>
的直接子元素才能正常工作,这就是您所发现的。因此,您无法将<mat-error>
包装在另一个组件中,并使用<mat-form-field>
中的该组件代替<mat-error>
。
但是,您不需要在错误和<mat-error>
元素之间建立一对一的关系 - <mat-error>
不是特殊对象 - 它只是<mat-form-field>
的容器显示错误内容。因此,您可以将错误逻辑放在组件中,并使用单个<mat-error>
内的组件。这可能是这样的:
表单字段HTML:
<mat-form-field class="col-6">
<input matInput formControlName="firstName">
<mat-error>
<app-mat-errors [field]="form.controls.firstName"></app-map-errors>
</mat-error>
</mat-form-field>
错误组件模板:
<ng-container *ngIf="field.hasError('required')">This field is required and cannot be empty</ng-container>
<ng-container *ngIf="field.hasError('other')">Some other error</ng-container>
etc....
如果您的字段可能有多个错误,请务必在* ngIf逻辑中考虑该错误,以避免出现多条消息。
您可能还想考虑将逻辑实现为一个函数而不是一个组件,从而可以更容易地编写逻辑:
<mat-form-field class="col-6">
<input matInput formControlName="firstName">
<mat-error>
{{getErrorMessage(form.controls.firstName)}}
</mat-error>
</mat-form-field>
getErrorMessage(control: FormControl): string {
if (control) {
if (control.hasError('required')) return 'This field is required and cannot be empty';
if (control.hasError('other')) return 'Some other error';
// etc.
}
return '';
}