我有一个自定义表单控件,里面有许多输入框,以及一些其他组件。当我的自定义验证器验证失败时,我发现所有输入框都读取表单验证失败并设置它们自己变成红色,但事实是它们没有问题,我如何禁用它们自动读取验证状态,并手动控制。
这是我制作的一个简化示例,您可以看到错误已传播到两个控件。如何精确控制错误显示? 示例
问题是错误与
formControl
“myData”有关。
当你有一个
<nz-form-item>
<nz-form-label [nzSpan]="7" nzRequired>my custom component</nz-form-label>
<nz-form-control [nzSpan]="12" nzHasFeedback>
<app-quality-rule formControlName="myData"></app-quality-rule>
</nz-form-control>
</nz-form-item>
ng-zorro 将“ant-input-group-wrapper-status-error”类添加到所有内部“inputs-group”
您可以与班级一起飞行,也可以不使用自定义表单控件并在组件中使用
viewProviders:[{ provide: ControlContainer, useExisting: FormGroupDirective}]
使用viewProviders,一切都改变了。看到现在 validateForm 被称为
this.validateForm = this.fb.group({
email: ['', [Validators.email, Validators.required]],
myData: this.fb.group({
value1: ['', [this.validate('value1')]],
value2: ['', [this.validate('value2')]],
}),
});
我们添加自定义函数验证为
validate(controlName: string) {
return (control: AbstractControl) => {
const myData = control.value as MyData;
const error: any = {};
if (controlName == 'value1' && !control.value)
return { [MyDataError.value1Error]: 'value1 error' };
if (controlName == 'value2' && !control.value)
return { [MyDataError.value2Error]: 'value2 error' };
return null;
};
}
quality-rile.component 变得更加简单 .ts
import {Component,Input} from '@angular/core';
import {ControlContainer, FormGroup, FormGroupDirective} from "@angular/forms";
import {MyDataError} from "../app.component";
@Component({
selector: 'app-quality-rule',
templateUrl: './quality-rule.component.html',
viewProviders:[{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class QualityRuleComponent {
protected readonly MyDataError = MyDataError;
@Input('group') set _(value:string){
setTimeout(()=>{
this.fromControl=this.form.form.get(value) as FormGroup
})
}
fromControl!:FormGroup
constructor(public form:FormGroupDirective){
}
}
但是 .html 发生了变化,看看我们如何添加 formGroup 和所有元素,就像我们不拆分表单一样
<ng-container *ngIf="fromControl" [formGroup]="fromControl">
<nz-form-item>
<nz-form-control nzHasFeedback>
<nz-input-group nzAddOnBefore="input1">
<input formControlName="value1" nz-input />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-alert
style="margin-top: 10px;margin-bottom: 5px"
*ngIf="fromControl?.hasError(MyDataError.value1Error, 'value1')"
nzType="error"
[nzDescription]="MyDataError.value1Error"
></nz-alert>
<nz-form-item>
<nz-form-control nzHasFeedback>
<nz-input-group nzAddOnBefore="input1">
<input formControlName="value2" nz-input />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-alert
style="margin-top: 10px;margin-bottom: 5px"
*ngIf="fromControl?.hasError(MyDataError.value2Error, 'value2')"
nzType="error"
[nzDescription]="MyDataError.value2Error"
></nz-alert>
</ng-container>
最后,app.component.html 变成这样
<form nz-form [formGroup]="validateForm">
<nz-form-item>
<nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label>
<nz-form-control [nzSpan]="12" nzHasFeedback>
<input
nz-input
formControlName="email"
placeholder="email"
type="email"
/>
</nz-form-control>
</nz-form-item>
<div nz-row>
<nz-form-label [nzSpan]="7" nzRequired>my custom component</nz-form-label>
<div nz-col [nzSpan]="12" nzHasFeedback>
<app-quality-rule group="myData"></app-quality-rule>
</div>
</div>
</form>
注意:也许,再过一段时间,我会尝试使用自定义表单控件,但我不太确定何时:(
更新一如既往,我们可以利用 Angular 将类添加到我们的输入中并编写一些类似的内容
<nz-form-item>
...
<!--use a template refrence variable "value1"-->
<input #value1 formControlName="value1" nz-input />
...
</nz-form-item>
<!--we needn't any more the *ngIf-->
<nz-alert [ngClass]="{'error-message':true,
'ng-invalid':value1.classList.contains('ng-invalid'),
'ng-dirty':value1.classList.contains('ng-dirty')}"
...></nz-alert>
并用作.css
.error-message{
display:none
}
.error-message.ng-invalid.ng-dirty{
display:block
}