具有动态值的最大值验证器

时间:2017-08-30 05:23:22

标签: angular angular4-forms

我有一个服务,它返回一个代表用户资金的值,我希望用户能够进行等于或小于总金额的交易。我试过使用像这样的最大验证:

valid() {
        const form: FormGroup = this._fb.group({
          fond: ['', [Validators.required]],
          serie: ['', [Validators.required]],
          account: ['', [Validators.required, Validators.min(1)]],
          value: ['', [Validators.required, Validators.min(1)]],
          subAccount: ['', [Validators.required, Validators.min(1)]]
        });
        return form;
      }

但是它不起作用,好像max()中的值必须从头开始设置,所以它只是将totalAmount假定为未定义。

4 个答案:

答案 0 :(得分:15)

更新已修改的问题:

使用此:

value: ['', [
  Validators.required, 
  Validators.min(1), 
  (control: AbstractControl) => Validators.max(this.totalAmount)(control)
]]

您可以使用以下语法实现此目的:

(control: AbstractControl) => Validators.max(this.totalAmount)(control)

为什么?

  • 当您提供Validators.max(this.totalAmount)时,它会使用给定参数(当前值this.totalAmount)创建验证函数,然后将其分配给表单控件。
  • 使用胖箭头功能时,分配给窗体控件的是胖箭头定义本身。每次调用胖箭头函数时(在有效性检查期间),它会重新评估Validators.max(this.totalAmount)并使用当前值this.totalAmount创建新的验证函数,从而使其成为动态。

答案 1 :(得分:0)

如果您使用反应形式,请执行以下操作:

将此添加到您的formBuilder.group

 offerPrice: [this.offer.offerPrice, [Validators.required, Validators.pattern('^\\d+(\\.\\d{1,2})?$'), Validators.pattern('^[1-9]+[0-9]*$'),
        (control: AbstractControl) => Validators.max(this.maxAmount)(control),
        (control: AbstractControl) => Validators.min(this.minAmount)(control)]],

在您的html上,如下所示使用

<div class=" form-group">
              <mat-form-field>
                <input class="form-control" matInput formControlName="offerPrice" placeholder="Gift Amount" [ngClass]="{'is-invalid': submitted && f.offerPrice.errors}"  *ngIf="!useSlab"/>
                <div *ngIf="submitted && f.offerPrice.errors">
                  <mat-error *ngIf="f.offerPrice.errors.required">This is required</mat-error>
                  <mat-error *ngIf="f.offerPrice.errors.min">Minimum offer price should be {{minAmount}}</mat-error>                  
                  <mat-error *ngIf="f.offerPrice.errors.max">Maximum offer price should be {{maxAmount}}</mat-error>
                  <mat-error *ngIf="f.offerPrice.errors.pattern">Price should be greater than zero</mat-error>
                </div>
              </mat-form-field>
            </div>

答案 2 :(得分:0)

仅对前面的答案做了一点补充,当您需要设置另一个具有相同表单的formControl的formControl的formControl的验证器的值时,您可以在不使用验证器的情况下初始化表单,然后在其后注册,如下所示:

const form: FormGroup = this._fb.group({
      from: [''],
      to: ['']
});

form.controls.from.setValidators([
    Validators.required,
    (control: AbstractControl) => Validators.max(this.form.controls.to.value)(control)
]);

to也是如此。

答案 3 :(得分:0)

另一种解决方案是使用 setValidators()

当您使用 setValidators() 时,其他人可以更清楚地理解代码,并且当您要使用的动态值可能会根据用户输入或与表单的其他交互而发生变化时,此解决方案也适用。

>

例如,您可以在组件中使用它:

  setInputValidation() {
    this.totalAmount = this.countryOfOrigin?.value === 'US' ? 40 : 30;
    this.value?.setValidators(Validators.max(this.totalAmount));
  }

然后您可以根据此动态值在模板中显示自定义错误:

 <mat-error *ngIf="value?.hasError('max')">
    Must be less than {{ totalAmount }}.
 </mat-error>

在我处理的一个复杂案例中,我在表单中有一个下拉列表,需要更改另一个输入的验证 max。所以我使用了上面的代码,然后简单地将它添加到下拉列表的 mat-select 中:

<mat-select formControlName="countryOfOrigin"
    (selectionChange)="setInputValidation()"
    name="country">
  <mat-option *ngFor="let country of countries" value="country">
    {{ country }}
  </mat-option>
</mat-select>

瞧,每次用户从下拉列表中进行选择时,输入的有效最大值都会发生变化,错误将根据新值显示。

注意:如果您的输入中有其他验证器,则您必须在使用 setValidators() 时添加它们。