我正在尝试处理一种大形式,即为每个部分创建一个自定义组件,将所有逻辑和自定义验证置于每个自定义组件中。基本上,每个部分都是子表单,每个部分都有助于大表单的验证过程。
我也在使用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问题?
希望我的解释很清楚 谢谢
答案 0 :(得分:0)
我认为您可能对mat-form-field
的预期目的感到困惑...重要的是要注意mat-form-field
与mat-form-fields
的奇异之处
在本文档中,“表单域”是指包装器组件
<mat-form-field>
和“表单域控件”是指<mat-form-field>
是自动换行的(例如,输入,文本区域,选择, 等)
https://material.angular.io/components/form-field/overview
尽管描述是开放的,但是...表单字段包装器的设计是1:1 ...意味着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