角2-自定义表单验证程序不起作用-无法读取null的属性“值”

时间:2019-05-22 04:51:39

标签: javascript jquery angular

我正在尝试创建自定义表单验证器,但我不断收到此错误。无法读取null的属性“值”。几天来,我一直在努力解决问题,这是我的FormGroup:

this.step1Form = this.fb.group({
                username: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(4),
                        this.checkUsername.bind(this)],
                }),
                email: new FormControl('', {
                        validators: [Validators.required,
                        Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
                }),
                password: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(8)],
                }),
                repeat: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(8)],
                }),
                });

这是我的checkUsername方法

checkUsername(g: FormGroup) {
                return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {
                        return typeof data["error"] != 'undefined' ? null : {'taken': true};
                }));
        }

这是this.dataService中的checkUsername方法

checkUsername(username):Observable<any> {
            return this.http.get(globals.baseUrl+'/user/' + username, {headers:this.utilService.getHeadersJson()}).map(this.utilService.map);
        }

我得到了错误:

  

无法读取null的属性“值”

在此行

return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {

我在做什么错?我试过没有这样的管道

checkUsername(g: FormGroup) {
    return this.dataService.checkUsername(g.get('username').value).subscribe(data => {
            return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}

但是那没有用,我还在不同的位置尝试过验证器,例如:

this.step1Form = this.fb.group({
        username: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(4)],
        }),
        email: new FormControl('', {
                validators: [Validators.required,
                Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
        }),
        password: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(8)],
        }),
        repeat: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(8)],
        }),
        }, { validator: this.checkUsername.bind(this)});

也没用。

请帮助!

我也尝试过这个:

username: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(4)],
                        asyncValidator: [this.checkUsername.bind(this)],

 }),

遇到此错误:

  

类型'{验证符:ValidatorFn []; asyncValidator:any [];   }'不能分配给'ValidatorFn |类型的参数。   AbstractControlOptions | ValidatorFn []'。对象文字只能   指定已知属性,并且'asyncValidator'在类型中不存在   'ValidatorFn | AbstractControlOptions | ValidatorFn []'。

1 个答案:

答案 0 :(得分:0)

角反应形式立即并经常调用验证器。在框架中实例化每个子控件时,表单组中的跨字段验证器将开始进行验证。

为防止其引发过早的验证错误,您可能需要确保已将相关控件实例化,如下所示:

checkUsername(g: FormGroup) {
    if (!g || !g.get('username')) {
        return null;
    }
    return this.dataService.checkUsername(g.get('username').value).subscribe(data => {
        return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}

您的第二次尝试似乎是一个更好的方向,因为它是'username'控件的异步验证器,但是asyncValidators属性中有一个错字(缺少's')。如果您未在函数中引用“ this”,则也可能不需要.bind(this)。

username: new FormControl('', {
  validators: [Validators.required, Validators.minLength(4)],
  asyncValidators: [this.checkUsername]
})

然后,您的验证程序仅处理单个表单控件而不是整个组,就像这样:

checkUsername(c: FormControl) {
    if (!c) { return null; }
    return this.dataService.checkUsername(c.value).subscribe(data => {
        return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}