关于angular:mat-error放在单独的组件上无法正确渲染

mat-error put to separate component not rendering properly

我想使用mat-errors在我的Angular 5 SPA中呈现服务器端错误。

这是我到目前为止所能完成的,

1
2
3
4
5
<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>

表单的每个字段看起来都相似。输入字段和下面的许多错误垫标签。在单个输入字段上附加了许多重复代码。同样,添加新的错误消息将导致将其添加到需要它的每个字段中。
我认为这是一个引入空间来管理错误消息的好地方,并通过表单控件注入它决定要显示的错误(我希望所有字段都具有常见错误消息)。

所以我想这样

1
2
3
4
<mat-form-field class="col-6">
    <input matInput formControlName="firstName">
    </app-map-errors>
</mat-form-field>

app-mat-errors组件模板中具有我们以前在每个单个字段中拥有的所有mat-error代码

1
2
3
<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....

通过这种方法,我无法正确渲染组件。

放置到时,<mat-error>标记嵌入在app-mat-errors标记中,并且不能正确显示(即使没有错误,它们也不会一直显示样式和可见状态)

有什么方法可以使组件不带有父标记地呈现angular?或者您对如何使其正常工作有任何想法?预先感谢。


<mat-error>元素必须是<mat-form-field>的直接子元素,才能正常工作,这是您所发现的。因此,您不能将<mat-error>包装在另一个组件中,而不能在<mat-form-field>中使用该组件代替<mat-error>

但是,您不需要在错误和<mat-error>元素之间具有一对一的关系-<mat-error>不是一个特殊的对象-它只是<mat-form-field>显示错误内容的容器。因此,您可以将错误逻辑放在组件内,而在单个<mat-error>中使用组件。这可能是这样的:

表单字段HTML:

1
2
3
4
5
6
<mat-form-field class="col-6">
    <input matInput formControlName="firstName">
    <mat-error>
        </app-map-errors>
    </mat-error>
</mat-form-field>

错误组件模板:

1
2
3
<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逻辑中说明该错误,以避免出现多个消息。

您可能还想考虑将逻辑实现为功能而不是组件,在这种情况下编写逻辑可能会更容易:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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 '';
}