Angular 6:如何使用索引插值为动态反应形式添加验证?
Angular 6: How to add validation to dynamic reactive form with index interpolation?
我正在尝试创建一个经过适当验证的动态反应表单。
基于业务逻辑,我们需要根据数据填充输入字段。我创建了一个变量调用 formErrors
并在字段无效时动态添加错误消息。我试图为错误添加 *NgIf
或 [hidden]
指令。但是,这是不允许的。 (以下跨度语法无效)
我可能有一个包含相关错误的 FormControl 列表(例如 wage_0、wage_1、wage_2、...)。如何将错误消息推送到 html 模板?最佳做法是什么?
组件html
<form *ngIf="cuList" [formGroup]="reportForm" role="form">
<p-accordionTab *ngFor='let cu of cuList; let counter = index'>
<div>
<div class="input-group">
<input class="form-control"
name="wages"
placeholder=""
formControlName="wages_{{ counter }}" <!-- dynamically name the formControl -->
currencyMask
[(ngModel)]="cu.wage"
[options]="{ prefix: '$ ', thousands: ',', allowNegative: false, precision: 0}"
maxlength="15"
required />
<div class="input-group-append">
<span class="input-group-text">.00</span>
</div>
</div>
<span [hidden]="formErrors.wages_{{counter}}"></span> <!-- show error message -->
<!-- or -->
<span *ngIf="formErrors.wages_{{counter}}"></span>
</div>
</p-accordionTab>
</form>
组件 ts:
export class EmployerCuListComponent implements OnInit {
private _accordion: Accordion;
@ViewChild('accordion') set content(content: Accordion) {
this._accordion = content;
}
reportForm: FormGroup;
formErrors = {};
cuList: EmployerCu[];
constructor(private _fb: FormBuilder) {}
ngOnInit() {
this._employercuService.getEmployerCu().subscribe(data => {
this.cuList = data;
if (this.cuList) {
this.createForm(this.cuList);
}
});
}
createForm(cuList: EmployerCu[]) {
const group = {};
cuList.forEach((cu, index) => {
group['wages_' + index] = ['', [Validators.required]];
this.formErrors['wages_' + index] = '';
});
this.reportForm = this._fb.group(group);
}
}
请帮忙!提前致谢!
我想出了另一个模板驱动表单的解决方案。我认为这对我们的动态案例来说是最好的。它允许通过适当的验证动态创建表单。
组件HTML
<p-accordion #accordion [hidden]="!cuList" [multiple]="true">
<p-accordionTab *ngFor='let cu of cuList; let counter = index'>
<form #form="ngForm" (ngSubmit)="form.form.valid" role="form" novalidate> <!-- create sub-form -->
<div class="row form-group col-md-12 pr-0">
<div class="col-md-4 pl-0 ml-0 mt-3 pr-0" [ngClass]="{ 'has-error': wages.invalid && (wages.dirty || wages.touched || form.submitted) }">
<div class="input-group">
<input class="form-control"
name="wages"
placeholder=""
#wages="ngModel" <!-- assign template variable -->
ngControl="wages"
currencyMask
[(ngModel)]="cu.wage"
[options]="{ prefix: '$ ', thousands: ',', allowNegative: false, precision: 0}"
maxlength="15"
required />
<div class="input-group-append">
<span class="input-group-text">.00</span>
</div>
</div>
<span *ngIf="wages.invalid && (wages.dirty || wages.touched || form.submitted)">Field cannot be blank. Please enter an amount.</span>
</div>
<button *ngIf="counter !== cuList.length-1" type="submit" class="btn btn-primary btn-normal float-right" (click)="openNext(cu)">Next</button>
</form>
</p-accordionTab>
</p-accordion>
组件 ts
export class EmployerCuListComponent implements OnInit {
@ViewChild('accordion') accordion: Accordion;
@ViewChildren('form') cuForms: QueryList<NgForm>;
constructor(private _employercuService: EmployerCuService) {}
ngOnInit() {
this._employercuService.getEmployerCu().subscribe(data => {
this.cuList = data;
});
}
formHasError() {
this.cuForms.some((cuForm, index) => {
if (cuForm.form.invalid) {
cuForm.form.controls['wages'].markAsTouched();
cuForm.form.controls['payments'].markAsTouched();
cuForm.form.controls['excessPayroll'].markAsTouched();
return true;
}
});
return false;
}
}
不确定这是否是最佳做法。但它解决了我的问题。我在 HTML 模板中推送表单创建并使用 @ViewChidren 获取表单数组并集中控制并充分利用 NgForm 在 component.ts.
中提供的属性和方法
如果您有更好的主意,请告诉我。谢谢!
我正在尝试创建一个经过适当验证的动态反应表单。
基于业务逻辑,我们需要根据数据填充输入字段。我创建了一个变量调用 formErrors
并在字段无效时动态添加错误消息。我试图为错误添加 *NgIf
或 [hidden]
指令。但是,这是不允许的。 (以下跨度语法无效)
我可能有一个包含相关错误的 FormControl 列表(例如 wage_0、wage_1、wage_2、...)。如何将错误消息推送到 html 模板?最佳做法是什么?
组件html
<form *ngIf="cuList" [formGroup]="reportForm" role="form">
<p-accordionTab *ngFor='let cu of cuList; let counter = index'>
<div>
<div class="input-group">
<input class="form-control"
name="wages"
placeholder=""
formControlName="wages_{{ counter }}" <!-- dynamically name the formControl -->
currencyMask
[(ngModel)]="cu.wage"
[options]="{ prefix: '$ ', thousands: ',', allowNegative: false, precision: 0}"
maxlength="15"
required />
<div class="input-group-append">
<span class="input-group-text">.00</span>
</div>
</div>
<span [hidden]="formErrors.wages_{{counter}}"></span> <!-- show error message -->
<!-- or -->
<span *ngIf="formErrors.wages_{{counter}}"></span>
</div>
</p-accordionTab>
</form>
组件 ts:
export class EmployerCuListComponent implements OnInit {
private _accordion: Accordion;
@ViewChild('accordion') set content(content: Accordion) {
this._accordion = content;
}
reportForm: FormGroup;
formErrors = {};
cuList: EmployerCu[];
constructor(private _fb: FormBuilder) {}
ngOnInit() {
this._employercuService.getEmployerCu().subscribe(data => {
this.cuList = data;
if (this.cuList) {
this.createForm(this.cuList);
}
});
}
createForm(cuList: EmployerCu[]) {
const group = {};
cuList.forEach((cu, index) => {
group['wages_' + index] = ['', [Validators.required]];
this.formErrors['wages_' + index] = '';
});
this.reportForm = this._fb.group(group);
}
}
请帮忙!提前致谢!
我想出了另一个模板驱动表单的解决方案。我认为这对我们的动态案例来说是最好的。它允许通过适当的验证动态创建表单。
组件HTML
<p-accordion #accordion [hidden]="!cuList" [multiple]="true">
<p-accordionTab *ngFor='let cu of cuList; let counter = index'>
<form #form="ngForm" (ngSubmit)="form.form.valid" role="form" novalidate> <!-- create sub-form -->
<div class="row form-group col-md-12 pr-0">
<div class="col-md-4 pl-0 ml-0 mt-3 pr-0" [ngClass]="{ 'has-error': wages.invalid && (wages.dirty || wages.touched || form.submitted) }">
<div class="input-group">
<input class="form-control"
name="wages"
placeholder=""
#wages="ngModel" <!-- assign template variable -->
ngControl="wages"
currencyMask
[(ngModel)]="cu.wage"
[options]="{ prefix: '$ ', thousands: ',', allowNegative: false, precision: 0}"
maxlength="15"
required />
<div class="input-group-append">
<span class="input-group-text">.00</span>
</div>
</div>
<span *ngIf="wages.invalid && (wages.dirty || wages.touched || form.submitted)">Field cannot be blank. Please enter an amount.</span>
</div>
<button *ngIf="counter !== cuList.length-1" type="submit" class="btn btn-primary btn-normal float-right" (click)="openNext(cu)">Next</button>
</form>
</p-accordionTab>
</p-accordion>
组件 ts
export class EmployerCuListComponent implements OnInit {
@ViewChild('accordion') accordion: Accordion;
@ViewChildren('form') cuForms: QueryList<NgForm>;
constructor(private _employercuService: EmployerCuService) {}
ngOnInit() {
this._employercuService.getEmployerCu().subscribe(data => {
this.cuList = data;
});
}
formHasError() {
this.cuForms.some((cuForm, index) => {
if (cuForm.form.invalid) {
cuForm.form.controls['wages'].markAsTouched();
cuForm.form.controls['payments'].markAsTouched();
cuForm.form.controls['excessPayroll'].markAsTouched();
return true;
}
});
return false;
}
}
不确定这是否是最佳做法。但它解决了我的问题。我在 HTML 模板中推送表单创建并使用 @ViewChidren 获取表单数组并集中控制并充分利用 NgForm 在 component.ts.
中提供的属性和方法如果您有更好的主意,请告诉我。谢谢!