-1

刚刚升级到 Angular 7.0.1 并遇到了 formControl 的 asyncValidator 的奇怪行为(我的 asyncValidator 指令链接到我的 formControl)。

在使用具有 asyncValidator 指令的输入初始化组件时,我没有将 asyncValidator 链接到我的 formControl,但在验证器中会触发“验证”功能(收集错误)!

formControl 上没有 asyncValidator 收集到的错误,但 asyncValidator 没有它们

在组件初始化和更改输入值(使用此 formControl)后,asyncValidator 神奇地出现并且一切都按预期工作。

asyncValidator 神奇地出现

问题是初始化输入的错误在计算并添加到控制时不显示。

在 Angular 6+ 版本中,一切都很好!

看截图。

有人遇到同样的问题吗?

4

2 回答 2

0

好吧,经过小的解决方法后,只有这个解决方案:

        if (!this._formControlStatus) {
            this._formControlStatus = status;

            /**
             * Should update component bindings after small timeout on first init.
             *
             * Otherwise validation (if exists) will not be desplayed untill focusing input.
             */
            timer(1).subscribe(() => {
                this.changeDetectorRef.detectChanges();
            });

            return;
        }

如果 id 没有兑现“_formControlStatus” - 意味着来自控件的输入是第一次初始化,并且在短暂延迟后评估“detectChanges”将使用输入更新视图:\

于 2018-10-27T14:39:24.067 回答
0

我错了,Angular 6+ 的行为相同,但显示验证错误。忘了提一下,我正在使用“OnPush”策略。

在 Angular 6+ 上:

  1. 在组件初始化时触发“formControl”的“statusChanges”事件,状态为“Valid”,没有链接“asyncValidator”
  2. 在我的指令(“asyncValidator”)中调用此“验证”函数之后,收集错误
  3. 当使用空输入初始化组件视图时,输入具有“无效”下划线和预期错误

在 Angular 7+ 上:

1-2。相同的行为

  1. 输入出现时没有“无效”下划线和错误,直到没有聚焦,当它被触摸(聚焦)时 - 出现错误:\

这是我的“asyncValidate”指令:

@Input()
public propertyName: string;

private get _businessObject(): BusinessBase {
    return this._fieldComponentBase.businessObject;
}

private _propertyChangedSubscription: Subscription;

constructor(private _fieldComponentBase: FieldComponentBase) {}

public ngOnDestroy() {
    this.unsubscribeFromPropertyChangedEvent();
}

public validate(abstractControl: FormControl): Promise<ValidationErrors> | Observable<ValidationErrors> {
    if (!this.propertyName) {
        throw new Error('Property name of business object was not provided.');
    }

    if (!this._businessObject) {
        throw new Error('Business object was not provided.');
    }

    return new Promise(resolve => {
        const errors: ValidationErrors = {};

        if (this._businessObject.shouldPristineFormControl(this.propertyName)) {
            abstractControl.markAsPristine();


     this._businessObject.removePropertyFormControlPristineStatus(this.propertyName);
        }

        if (abstractControl.dirty) {
            this.unsubscribeFromPropertyChangedEvent();

            this._propertyChangedSubscription = this._businessObject.propertyChanged
                .subscribe((propertyChangedEvent: PropertyChangedEvent) => {
                    if (propertyChangedEvent.propertyName !== this.propertyName) {
                        return;
                    }

                    this.unsubscribeFromPropertyChangedEvent();

                    this.setErrors(errors);

                    resolve(errors);
                });
        } else {
            this.setErrors(errors);

            resolve(errors);
        }
    });
}

private setErrors(errors: ValidationErrors) {
    this._businessObject.getBrokenRules(undefined, this.propertyName).forEach((brokenRule, index) => {
        errors[index] = brokenRule.message;
    });
}

private unsubscribeFromPropertyChangedEvent() {
    if (!this._propertyChangedSubscription) {
        return;
    }

    this._propertyChangedSubscription.unsubscribe();

    this._propertyChangedSubscription = undefined;
}

这是我的表单控件的“statusChanges”监听器:

this.formControl.statusChanges.subscribe((status: 'VALID' | 'INVALID' | 'PENDING') => {
        if (!this._formControlStatus) {
            this._formControlStatus = status;

            return;
        }

        if (status === 'PENDING' || status === 'VALID' && status === this._formControlStatus) {
            return;
        }

        this._formControlStatus = status;

        /**
         * Should update component bindings if error calculation took too long.
         */
        this.changeDetectorRef.markForCheck();
    });
于 2018-10-26T15:01:32.767 回答