错误加上自定义表单控件组件

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

我正在尝试创建一个自定义的MatFormFieldControl,它也实现了ControlValueAccessor。

我想从一个已知的用例开始:密码表单。

计划:创建一个表单字段,该字段获取单个字符串,但在其中包含自己的表单,以对confirmPassword字段添加验证。

我创造了一个StackBlitz with a working implementation

每次调用错误状态变量时,我都会检查两个字段之间是否存在不匹配,并更新ngControl上的错误,以便它可以反映到外部。

首先正确显示错误状态,但如果您匹配密码而不是再次错配它们,则会抛出此错误:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: null'. Current value: 'ngIf: [object Object]'.

我在网上找不到很多关于这个的文档,我不确定什么时候将错误添加到错误对象的正确位置

谁知道我怎么能避免这个错误?

提前致谢

get errorState() {
  const missmatch = this.weightForm.value.password !== this.weightForm.value.confirmPassword;

  if (missmatch) {
    this.ngControl.control.setErrors({ missmatch }, { emitEvent: false });
  }

  return (this.ngControl.errors !== null || missmatch) && !!this.ngControl.touched;
}

这里的想法是创建一个“关注点分离”,外部形式不知道confirmPassword,因为它更像是一个“验证”字段,而不是“数据”字段,如果这是有道理的。

这种关注点分离的另一个例子是将代码编辑器作为表单字段,并使代码编辑器验证反映到外部,而不将代码编辑器本身暴露给外部。

angular angular-forms angular-material-6
1个回答
1
投票

测试你的StackBlitz示例我已经看到删除app.component上的* ngIf mat-error解决问题保持不变的表单输入的“错误报告功能”,我不知道这是否可以解决你的问题真实的网站,但我认为值得一试。

但我真正建议你做这种工作(密码匹配验证)是依靠Angular表单验证器(这里形式文档:https://angular.io/guide/form-validation)这种方法更安全,因为你不需要通过变量强制进行错误检查,但是单独理解字段是否无效的形式。

没有标准的验证器可以检查2个字段是否包含相同的文本,但是您可以构建自己想要的自定义验证器。

如果这有用,我将分享我通常用于密码检查的自定义验证器的语法(仅作为跟踪,确保您必须修改某些内容才能使其正常工作):

export function mismatchValidator(): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} | null => {
        if (control.parent) {
            if (control.parent.get('password').value !== control.parent.get('password_confirmation').value) {
                return {mismatch: true};
            } else {
                return null;
            }
        } else {
            return null;
        }
    };
}

有关如何实现表单控制器,验证器和自定义验证器的其他信息可以在Angular站点上找到。

这是关于你的问题的一个有趣的article,如果你选择不实现表单验证器,它可能有助于你理解你的问题所在。

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