【问题标题】:Custom required validation on fields in Angular 6Angular 6中字段的自定义所需验证
【发布时间】:2019-01-28 14:15:24
【问题描述】:

我正在使用 Angular 6 和 Material 形式。

在一个 div 中有 3 个字段,2 个日期选择器和 1 个输入文本字段。我们只需要,如果在字段中输入了一个值,那么所有值都应该是强制性的。

我试过的方法是:

HTML

<div class="flex-container PromotionalPriceInfo">

    <span class="flex-item bold small">Promotional</span>

    <mat-form-field class="flex-item">

        <input matInput [matDatepicker]="promotionalPriceStartDatePicker" placeholder="Promotional Price Start Date" formControlName="promotionStartDate"
        />

        <mat-datepicker-toggle matSuffix [for]="promotionalPriceStartDatePicker"></mat-datepicker-toggle>

        <mat-datepicker #promotionalPriceStartDatePicker></mat-datepicker>

    </mat-form-field>

    <mat-form-field class="flex-item">

        <input matInput [matDatepicker]="promotionalPriceEndDatePicker" placeholder="Promotional Price End Date" formControlName="promotionEndDate"
        />

        <mat-datepicker-toggle matSuffix [for]="promotionalPriceEndDatePicker"></mat-datepicker-toggle>

        <mat-datepicker #promotionalPriceEndDatePicker></mat-datepicker>

    </mat-form-field>

    <mat-form-field class="flex-item">

        <input matInput type="number" placeholder="New Price" formControlName="promotionPrice" />

    </mat-form-field>

</div>

组件.ts onInit() 我将自定义验证器设置为:

this.storeServiceForm.get('promotionStartDate').setValidators(requiredPromotionalFields);

this.storeServiceForm.get('promotionEndDate').setValidators(requiredPromotionalFields);

this.storeServiceForm.get('promotionPrice').setValidators(requiredPromotionalFields);

自定义验证器代码为:

export function requiredPromotionalFields(control: FormControl) {
    const promotionStartDate = control.parent.get('promotionStartDate').value;
    const promotionEndDate = control.parent.get('promotionEndDate').value;
    const promotionPrice = control.parent.get('promotionPrice').value;
    return ((!promotionStartDate && !promotionEndDate && !promotionPrice) || control.value) ? null : {
        required: true
    };
}

如果在加载页面时任何字段中有值,但它不会在任何字段中的值更改时重新验证其他字段

如果我将下面的代码用作:

 this.storeServiceForm.get('promotionStartDate').valueChanges.subscribe(value => {
            this.storeServiceForm.controls['promotionStartDate'].updateValueAndValidity({ emitEvent: false });
            this.storeServiceForm.controls['promotionEndDate'].updateValueAndValidity();
            this.storeServiceForm.controls['promotionPrice'].updateValueAndValidity();
        });

        this.storeServiceForm.get('promotionEndDate').valueChanges.subscribe(value => {
            this.storeServiceForm.controls['promotionStartDate'].updateValueAndValidity();
            this.storeServiceForm.controls['promotionEndDate'].updateValueAndValidity({ emitEvent: false });
            this.storeServiceForm.controls['promotionPrice'].updateValueAndValidity();
        });

        this.storeServiceForm.get('promotionPrice').valueChanges.subscribe(value => {
            this.storeServiceForm.controls['promotionStartDate'].updateValueAndValidity();
            this.storeServiceForm.controls['promotionEndDate'].updateValueAndValidity();
            this.storeServiceForm.controls['promotionPrice'].updateValueAndValidity({ emitEvent: false });
        });    

但上面的代码分解为错误,例如超出最大调用堆栈大小。只有第一次我更改了任何值,然后也只有验证正在处理价格变化而不是其他字段。并挂起浏览器。

这个可以解决吗,还是有其他办法?

【问题讨论】:

标签: angular typescript validation angular-material


【解决方案1】:

您需要在第二个 updateValueValidity 方法中添加一个参数,因为您订阅了一个您更新的值。所以无限循环。

参数为{emitEvent: false;} https://angular.io/api/forms/AbstractControl#updateValueAndValidity

【讨论】:

  • 我已将订阅更改如下:但是第一次我在字段中输入的任何值它都会进入无限循环,而不是从第二次开始,并且验证仅适用于价格字段更改而不适用于其他人:
  • 然后请提供一个 jsfiddle 什么的
  • 我从来没有用过这样的东西,我已经打开了,但是如果我粘贴太多的 html 和 ts 它将无法独立运行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 2023-04-03
相关资源
最近更新 更多