【问题标题】:Maximum value validator with dynamic value具有动态值的最大值验证器
【发布时间】:2018-02-07 16:48:12
【问题描述】:

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

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 为未定义。

【问题讨论】:

  • 使用管道。将此动态值传递给管道并验证最大值
  • 不,除了转换值之外,请不要使用管道。

标签: angular angular4-forms


【解决方案1】:

更新您已编辑的问题:

使用这个:

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 的当前值创建新的验证函数,从而使其动态化。

【讨论】:

  • 你能介绍一下这个语法吗?我已经用我用于验证的代码更新了这个问题,我应该如何实现它? 'value' 是我要验证的。
  • 如果我需要一个变量(或输入)的最小值和最大值?我该怎么办@Harry Ninh?
【解决方案2】:

只是对前面几个答案的一点补充,当你需要设置同一个表单的另一个formControl的一个formControl的validator的值时,你可以在没有validators的情况下初始化表单,然后注册,就像这样:

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】:

    如果您使用的是响应式表单,请执行以下操作:

    将此添加到您的 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>
    

    【讨论】:

      【解决方案4】:

      一个强大而清晰的解决方案是使用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() 时添加它们。

      【讨论】:

      • 在setValidators 之后,您还必须调用updateValueAndValidity() 才能使新验证生效。
      猜你喜欢
      • 2015-12-19
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      相关资源
      最近更新 更多