Angular Material和嵌套的mat-form-field的CSS问题:错误状态下的内部mat-form-field导致父级看起来处于错误状态

时间:2018-11-22 00:34:59

标签: angular angular-material

我正在尝试处理一种大形式,即为每个部分创建一个自定义组件,将所有逻辑和自定义验证置于每个自定义组件中。基本上,每个部分都是子表单,每个部分都有助于大表单的验证过程。

我也在使用Angular Material,我的自定义组件正在custom form field control实现MatFormField<T>界面中,通过这种方式,我将能够使用漂亮的外观来显示错误和提示整个组件。

因此,我将自定义组件包装在<mat-form-field>内,甚至将自定义组件模板内子表单的字段也包装在<mat-form-field>中。

但是我对这个解决方案和Angular Material有疑问。 当子表单中的字段无效时,将正确显示自定义组件的<mat-error>,甚至显示内部表单字段的<mat-error>。 问题还在于所有其他字段都变成红色,就像它们无效一样,但实际上不是!

这里是一个示例: https://stackblitz.com/edit/angular-2h2fql?embed=1&file=src/app/app.component.ts

每个字段都是必填字段,只需尝试清除其中一个或添加新行,其他所有字段都将变成红色。

我认为这只是CSS的东西,因为当<mat-form-field>无效时,会显示<mat-error>消息类,并且将mat-form-field-invalid类应用于宿主元素<mat-form-field>将无效字段变成红色。

我的问题是:有人知道是否有可能手动显示<mat-error>或将自定义表单控件设置为错误状态,而无需将.mat-form-field-invalid类应用于宿主元素吗?

根据我的理解,您可以在此处看到该类绑定到错误状态

https://github.com/angular/material2/blob/master/src/lib/form-field/form-field.ts#L120

但是我找不到解决该问题的理想解决方案。

我尝试应用ShadowDOM视图封装,但是无法正常工作。

我不能简单地将自定义表单控件放在<mat-form-field>内,它将很好地工作,并且<mat-error>会显示出来,但是不是以材料设计的方式。

我弄错了吗,还是某些Angular Material问题?

希望我的解释很清楚 谢谢

1 个答案:

答案 0 :(得分:0)

我认为您可能对mat-form-field的预期目的感到困惑...重要的是要注意mat-form-fieldmat-form-fields的奇异之处

  

在本文档中,“表单域”是指包装器组件   <mat-form-field>和“表单域控件”是指   <mat-form-field>是自动换行的(例如,输入,文本区域,选择,   等)

https://material.angular.io/components/form-field/overview


尽管描述是开放的,但是...表单字段包装器的设计是1:1 ...意味着1个包装器,1个控件。

  • 查看表单字段的所有stackblitz示例,您将看到 1:1标准。

https://material.angular.io/components/form-field/examples

通过将多个mat-form-fields封装在父mat-form-field中,您实际上将它们全部变成了一个大mat-form-field,就{{1}的样式而言,这将所有控件视为一个控件} ...如果一个无效,那么它们都是无效的,因为它是一个巨大的errorState


在您的form-field中使用以下表单域包装器,您会发现问题在您的people-list.component.html示例中得到了重复。

OUTSIDE MAT FORM FIELD

您可能希望探索使用以下类似方法在错误时复制表单域样式的方法。

<div [formGroup]="form"> <mat-form-field> <div formArrayName="rows" *ngFor="let p of rows.controls; let i=index"> <div [formGroupName]="i" fxLayout="row" fxLayoutAlign="space-around center"> <mat-form-field hintLabel="row number {{ i }}" class="full-width"> <input matInput type="text" formControlName="name"/> <mat-hint align="end">Valid: {{ p.get('name').valid }}</mat-hint> <mat-error *ngIf="p.get('name').hasError('required')">required</mat-error> </mat-form-field> <mat-form-field class="full-width"> <mat-select placeholder="Select state" formControlName="state"> <mat-option *ngFor="let state of stateList" [value]="state.abbreviation"> {{state.name}} </mat-option> </mat-select> <mat-hint align="end">Valid: {{ p.get('state').valid }}</mat-hint> <mat-error *ngIf="p.get('state').hasError('required')">required</mat-error> </mat-form-field> <button class="glyphicon glyphicon-remove pull-right" *ngIf="rows.length > 0" (click)="removeStep(i)">Remove</button> <br> </div> </div> <br> <button [disabled]="!rows.valid" (click)="addStep()" type="button" color="primary" *ngIf="rows.length < maxlength"> <span translate>ADD</span> </button> </mat-form-field> </div> 中创建mat-form-field-underline

app.component.scss

然后在HTML中使用它并复制.matFormFieldUnderline{ bottom: 1.25em; background-color: rgba(0,0,0,.42); height: 1px; margin-top:5px; } 样式

mat-form-field