【问题标题】:How to implement Custom Async Validator in Angular2/4/5如何在 Angular2/4/5 中实现自定义异步验证器
【发布时间】:2016-06-01 23:41:21
【问题描述】:

1. Angular 还支持它吗?请参阅this 公开问题

2.如果是,那么下面的代码有什么问题

export class someClass{

    myForm:ControlGroup;

    constructor(public http:Http, public formBuilder:FormBuilder)
       this.myForm = formBuilder.group({
            ImageId: ["", Validators.required, this.asynValidator]
    });

    asyncValidator(control: Control): {[key: string]: any} {

        return new Promise (resolve => {

          let headers = new Headers();
          headers.append('Content-Type', 'application/json');

          this.http.get('http://localhost/ImageIdValidate?id='+ control.value, {headers:headers})
                .map(res => res.json())
                .subscribe(data => {
                    console.log(data);
                    if(data != null) {
                        resolve({"duplicate": true})
                    }
                    else resolve(null);      
                })
            });
        });
      }
    }

它甚至不发出服务器请求。

【问题讨论】:

    标签: typescript angular


    【解决方案1】:

    对于较新版本的 Angular,但在 5.0.0 之前的版本,您可以添加异步验证器作为表单控件的第三个参数:

    myControl: ['', [Validators.required], [this.asyncValidator.bind(this)]]
    

    5.0.0 版本开始,您现在可以像这样标记验证器:

    myControl: ['', {validators: [Validators.required], 
                     asyncValidators:[this.asyncValidator.bind(this)]}]
    

    【讨论】:

    • 我刚刚实现了一个异步验证功能,还得在组件中添加NG_ASYNC_VALIDATORS provider! (这是一个令人讨厌的魔法!!)
    【解决方案2】:

    大家好,感谢您的解决方案。 但是它对我来说并没有开箱即用。

    问题是异步验证器必须是作为验证器一部分的下一个参数。所以对我有用的是

    this.myForm = formBuilder.group({
            ImageId: ["",    
               [Validators.required], 
               [this.asynValidator.bind(this)]]
    });
    

    还有啊!!头痛消失了。 希望它可以帮助某人。

    【讨论】:

    • 我能看到的唯一区别是你添加了一些额外的 [] 与答案帖子相比。而且您还没有提到为什么需要额外的 [] 。这不是一个有用的分析器
    • 额外的 [] 括号是必需的,因为现在必须将异步验证器列为第三个参数。同步验证器列在第二个参数中,异步验证器列在第三个参数中。
    【解决方案3】:

    您需要将您的方法绑定到组件实例本身,如下所述:

    this.myForm = formBuilder.group({
                ImageId: ["",    
                   Validators.required, 
                   this.asynValidator.bind(this)]
        });
    

    否则您将无法使用 http 属性来执行您的请求。

    本文还可以为您提供一些关于异步表单验证的提示(请参阅“异步验证”部分):

    【讨论】:

    • 事实上,这就是 JavaScript 的工作方式。当您引用一个方法时,您会丢失它所附加的对象。您可以使用 bind 方法强制执行此操作...
    • 当我开始认为有一天我会成为一名职业选手时,这样的事情会让我发笑。但无论如何,this question 是否相关?
    • 事实上,JavaScript 中的 OOP 与 Java 和 C++ 等语言的 OOP 不同。使用 class 关键字,您不会像使用语言那样真正定义“真正的”类。 JavaScript 使用基于原型的 OOP。是的,您引用的问题与此问题有关。
    • 还有@ThierryTemplier 的另一个答案showing an alternative to .bind() using a closure
    猜你喜欢
    • 2017-09-08
    • 1970-01-01
    • 2023-03-12
    • 2018-04-16
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多