Angular:跨字段验证不适用于setError()

问题描述 投票:0回答:3

我有一个跨域验证方法,如果以下条件之一为真,则该方法将失败:

  • [country == 'United States'stateSelect为空
  • [country != 'United States'stateText为空

countrystateSelect都是<select>项目,而sateText<input type="text">。当我加载页面country = 'United States'stateSelect = {name: 'Alabama', abbr: 'AL'}时,所有值均正确评估。

如果我在选择中将国家/地区更改为另一个值,然后将其更改回United States,它将正确评估,但是我的按钮保持禁用状态。

<form [formGroup]="purchase" class="forum-purchase__grid">
  <!-- inputs and selects -->
  <button [disabled]="purchase.invalid">Next</button>
</form>

该组件看起来像这样:

    public constructor() {
        this.purchase = new FormGroup({
            stateSelect: new FormControl(this.selectedState),
            stateText: new FormControl(''),
            country: new FormControl(this.selectedCountry, [Validators.required]),
        }, { validators: [this.stateRegionValidator] });
    }

    private stateRegionValidator(formGroup: FormGroup): ValidationErrors | null {
        const stateSelect = formGroup.get('stateSelect');
        const stateText = formGroup.get('stateText');
        const country = formGroup.get('country');

        // Validate the fields
        if (country.value === 'United States' && !stateSelect.value) {
            stateSelect.setErrors({ 'badState': true });
            return { 'badState': true };
        } else if (country.value !== 'United States' && !stateText.value.trim().length) {
            stateText.setErrors({ 'badRegion': true });
            return { 'badRegion': true };
        }

        // The validation was successful.
        return null;
    }

我确实注意到,如果我删除了这两行,这行得通,但是,然后在输入中我没有得到错误样式:

stateSelect.setErrors({ 'badState': true });
stateText.setErrors({ 'badRegion': true });

Working example

javascript angular typescript
3个回答
1
投票
问题是您呼出的内容-您需要删除setErrors呼叫。这些是您的

group验证器的副作用,该验证器可对表单进行整体验证。如果这些错误在各个字段上设置了错误,则无法解除错误。

您可能应该为每个使用组验证器函数中的逻辑的字段编写自定义验证器,同时不调用setErrors并仅返回null或值。或者保留组验证器,并在

group

出现错误时显示单个错误。

1
投票
因此您的按钮仍处于禁用状态,因为您没有从其他表单控件中删除先前设置的错误。

当您在return null;上方添加以下内容时,它将起作用:

stateSelect.setErros(null); stateText.setErrors(null);


0
投票
[在某些情况下,我需要做这样的事情。聆听价值变化:

<select [(ngModel)]="selectedCountry" (ngModelChange)="test($event)" formControlName="country">

以及在TS中:

countryUpdate($event: string) { if ($event == 'United States') { this.purchase.controls.stateText.clearValidators(); } else { this.purchase.controls.stateText.setValidators([this.stateRegionValidator]); } this.purchase.updateValueAndValidity(); }

© www.soinside.com 2019 - 2024. All rights reserved.