微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular FormArray 中的自定义验证比例总和必须为 100%

如何解决Angular FormArray 中的自定义验证比例总和必须为 100%

我创建了一个 angular 的 formArray 来表示 Nominee 的分布,它有两个字段 Name 和 Proportion。加号按钮(+)添加新行,(X)按钮删除当前行。现在我想编码一个验证,这样总比例列必须是 100%(无论它包含多少被提名者的名字)
例如
无姓名比例
1 安迪 100
(比例总和为100)
----------
例2
无姓名比例
1 安迪 60
2 布鲁斯 40
(比例总和为 100)
---------
例3
无姓名比例
1 安迪 60
2 布鲁斯 20
3巧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: ['',gratuityProportion: ['',Validators.pattern('^[0-9]*$'),proportionValidator] ],gender:['',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;}

}
    
    }

现在,我的问题是我应该按比例编写什么代码.validator.ts来实现条件?

解决方法

Straight from the docs

const arr = new FormArray(
  [
    new FormControl('Nancy'),new FormControl('Drew')
  ],{
   validators: myValidator //<- this is where your proportion validator goes
  }
);

在你的情况下,它看起来像这样:

    this.FormNominees = this.fb.group({
      itemRows: this.fb.array(
        [
          this.initItemRow()
        ],{ 
           validators: proportionValidator 
        }
      )
    });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。