【发布时间】:2021-06-06 07:49:21
【问题描述】:
我创建了一个有角度的 formArray 来表示被提名人的分布,它有两个字段 Name 和 Proportion。加号按钮 (+) 添加新行, (X) 按钮删除当前行。现在我想编写一个验证代码,使总比例列必须为 100%(无论它包含多少被提名者的名字)
例如
无姓名比例
1 安迪 100
(比例之和为100)
----------
例2
无姓名比例
1 安迪 60
2布鲁斯40
(比例之和为100)
---------
例 3
无姓名比例
1 安迪 60
2 布鲁斯 20
3 Ciao 20
(比例之和为100)
---------
这是我的 component.html 代码
<h5>Nominees</h5>
<div class="row">
<form novalidate [formGroup]="FormNominees">
<div clas="col-xs-12 form-group marL40">
<div formGroupName="itemRows">
<ng-container *ngIf="FormNominees.controls.itemRows!=null">
<div *ngFor="let itemrow of FormNominees.controls.itemRows.controls; let i = index"
[formGroupName]="i">
<div class="row">
<mat-form-field
class="example-full-width d-block input-small-size col-sm-2.4"
appearance="outline">
<input matInput placeholder="Name" formControlName="name">
<mat-error *ngIf="f9.name.touched && f9.name.errors?.required">It is mandatory
</mat-error>
<mat-error *ngIf="f9.name.touched && f9.name.errors?.pattern">Can only contain characters.
</mat-error>
</mat-form-field>
<mat-form-field
class="example-full-width d-block input-small-size col-sm-2.4"
appearance="outline">
<input matInput placeholder="Relationship"
formControlName="relationship">
<mat-error *ngIf="f9.relationship.touched && f9.relationship.errors?.required">It is mandatory
</mat-error>
</mat-form-field>
<mat-form-field
class="example-full-width d-block input-small-size col-sm-2.4"
appearance="outline">
<mat-select formControlName="gender" placeholder="Gender">
<mat-option value="Male">Male</mat-option>
<mat-option value="Female">Female</mat-option>
<mat-option value="Other">Other</mat-option>
</mat-select>
<mat-error *ngIf="f9.gender.touched && f9.gender.errors?.required">It is mandatory
</mat-error>
</mat-form-field>
<mat-form-field
class="example-full-width d-block input-small-size col-sm-2.4"
appearance="outline">
<input matInput placeholder="phone" formControlName="phone">
<mat-error *ngIf="f9.phone.touched && f9.phone.errors?.required">It is mandatory
</mat-error>
<mat-error *ngIf="f9.phone.touched && f9.phone.errors?.pattern">Can only contain numbers.
</mat-error>
</mat-form-field>
<mat-form-field
class="example-full-width d-block input-small-size col-sm-2.4"
appearance="outline">
<input matInput placeholder="Proportion"
formControlName="gratuityProportion">
<mat-error *ngIf="f9.gratuityProportion.touched && f9.gratuityProportion.errors?.required">It is mandatory
</mat-error>
<mat-error *ngIf="f9.gratuityProportion.touched && f9.gratuityProportion.errors?.pattern">Can only contain numbers.
</mat-error>
<mat-error *ngIf="f9.gratuityProportion.touched && f9.gratuityProportion.errors?.proportionValidator">Total must be 100%.
</mat-error>
</mat-form-field>
<div class="col-sm-2.4">
<button (click)="deleteRow(i)" class="btn btn-danger">x</button>
<!-- </div>
<div class="form-group"> -->
<button type="button" (click)="addnewRow()"
[disabled]="FormNominees.invalid"
class="btn btn-primary">+</button>
</div>
</div>
</div>
</ng-container>
</div>
</div>
</form>
</div> <br>
这是我的 component.ts 代码
import { proportionValidator } from './proportion.validator';
@Component({
selector: 'app-component',
templateUrl: './component.component.html',
styleUrls: ['./component.component.scss']
})
export class GratuityComponent implements OnInit {
FormNominees: FormGroup;
TotalRow: number;
itemFB: any;
constructor(private fb: FormBuilder) {
}
ngOnInit(): void {
this.FormNominees = this.fb.group({
itemRows: this.fb.array([this.initItemRow()])
});
initItemRow() {
this.itemFB = this.fb.group({
name: ['', [Validators.required, Validators.pattern('[a-zA-Z0-9. ]*' )]],
relationship: ['', Validators.required],
phone: ['', [Validators.required, Validators.pattern('[a-zA-Z0-9. ]*' )]],
gratuityProportion: ['', [Validators.required, Validators.pattern('^[0-9]*$'), proportionValidator] ],
gender:['', Validators.required],
employeeUniqueId: '00000001-0001-0001-0001-000000000001'
})
return this.itemFB;
}
addnewRow() {
const control = <FormArray>this.FormNominees.controls['itemRows'];
control.push(this.initItemRow())
}
deleteRow(index: number) {
const control = <FormArray>this.FormNominees.controls['itemRows'];
// control.push(this.initItemRow())
if (control != null) {
this.TotalRow = control.value.length;
}
if (this.TotalRow > 1) {
control.removeAt(index);
} else {
alert('One record is mandatory');
return false;
}
}
get f9() {return this.itemFB.controls;}
}
}
现在,我的问题是要在proportion.validator.ts中写什么代码来达到这个条件?
【问题讨论】:
-
比例验证器必须在 FormArray 上,所以检查一下:Create a form array with array-level validators
-
我无法理解你在说什么。你能写出那一行吗?我会得到线索。
标签: javascript angular typescript angular-reactive-forms formarray