一般:在angular2 asynchonious验证 [英] General: asynchonious validation in angular2

查看:506
本文介绍了一般:在angular2 asynchonious验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于夫妇晚上我打在augular2表单验证。

所有基本病例均容易实现,而且他们工作得很好,但我坚持异步验证。我创建了一个非常小的例子 http://plnkr.co/edit/Xo8xwJjhlHkXrunzS8ZE 才没有工作。

据测试从model_spec.ts注册通过创建假设在上班途中对照组的状态已更新为挂起后应触发一个事件

  builder.group({登录:[,Validators.required,validationFuctionWhichReturnsPromise]

我一个完整的晚上花在发现这code已α-46被释放(我用α-45)和更新depencies后异步验证开始工作。该功能是非常新鲜的,不完全记录,但

(对于那些谁没有尝试过),基本上异步的验证是有一个控制参数,并返回一个承诺,其验证结果的功能。有两种方法来注册的验证。 1)我在示例中使用; 2)作为通过NG_ASYNC_VALIDATORS提供验证指令(见UniqLoginValidator和NgFormControl之一,看看它是如何工作的)。您可以撰写多个验证器(没有测试,但功能要做到这一点是code,看的 https://github.com/angular/angular/commit/cf449dd )。

但是,当我终于达到启动和运行验证一个新的问题来了。异步验证器是完美的把它用在服务器端验证。但是,验证每个KEYUP后model.fe的每次更改后调用。因此,如果我们将每个键后发送请求到服务器时,它也不会太有效的方式)我检查它是如何在角度1完成,它们是debouce验证事件的可能性。

我的问题是:


  1. 如何实现油门或异步验证debouce?我看到一些想法,但他们没有被罚款(主要是因为他们需要改变角度code本身)。有没有做到这一点,而无需等待新的角度发布任何有效的方法是什么?

我在想翘曲与debouce(从underscorejs)一个验证器的功能,但它不会工作,因为角度希望每次都获得一个有效的承诺。

我的第二个,虽然是如果引擎盖下的所有事件中使用RxJs那么也许我可以在事件流适用debouce负责验证。在model.ts从验证返回的承诺是变化观察到并加入一个新的认购。我们不必OBS(观测)的任何访问那里申请debouce。

<醇开始=2>
  • 有什么办法或ID改变,容易延伸到表单验证控制?

  • 我发现在如何触发表校验器在angular2

    PS有相关的异步验证另一个问题,它仍然是开放的 https://开头github上。 COM /角/角/问题/ 1068


    解决方案

    下面是你可以用它来抖所有的异步验证一个辅助类:

     进口{}组件从angular2 /核心;
    从进口观测{}rxjs /可观察到的';
    从rxjs /观察者进口{}观察员;
    进口'rxjs /添加/运营/ debounceTime';
    进口'rxjs /添加/运营/ distinctUntilChanged';
    进口{}控制从angular2 /通用';出口类AsyncValidator {
    _Validate;构造函数(验证:(控制:控制)=&GT;如有,debounceTime = 1000){
        让源:任何=新观测((观察员:观察&lt;控制&GT;)= GT; {
            this._validate =(对照组)=&GT; observer.next(对照组);
        });    source.debounceTime(debounceTime)
            .distinctUntilChanged(NULL,(X)=&GT; x.control.value)
            .MAP(X =&GT; {返回{承诺:验证器(x.control),解析器:x.promiseResolver};})
            。订阅(
                (X)=&GT; x.promise.then(resultValue =&GT; x.resolver(resultValue)
                (E)=&GT; {的console.log(异步校验错误:%s',E); }));
    }私人_getValidator(){
        回报(控制)=&GT; {
            让promiseResolver;
            令p =新希望((解析)=&GT; {
                promiseResolver =决心;
            });
            this._validate({控制:控制,promiseResolver:promiseResolver});
            回磷;
        };
    }静态防抖动(验证:(控制:控制)=&GT;如有,debounceTime = 400){
        VAR asyncValidator =新本(验证,debounceTime);
        返回asyncValidator._getValidator();
    }
    }

    然后,所有你需要做的,其中使用异步验证只是换你验证这个电话,写你的验证器一样的,你通常会:

      AsyncValidator.debounce(控制=&GT; this.asyncValidator(控制));

    下面是一个例子用法:

     出口类AppComponent {
    形式:ControlGroup;构造函数(私人_formBuilder:FormBuilder){
        VAR验证= AsyncValidator.debounce(控制=&GT; this.asyncValidator(控制));    this.form = _formBuilder.group({
            名称:['',Validators.required,验证]
        });
    }asyncValidator(控制):任何{
        令p =新希望(解析= GT; {
            //从服务器的信息获取需要验证控制        如果(control.value ==='有效值'){
                解决(NULL);
            }其他{            解决({
                    asyncValidator:{
                        有效:假的
                    }
                });
            }
        });
        回磷;
    }
    }

    Since couple evening I've played with form validation in augular2.

    All basic cases were easy to implement and they works fine but I stick with asynchronous validation. I have created a very tiny example http://plnkr.co/edit/Xo8xwJjhlHkXrunzS8ZE and it didn't work.

    According to test "should fire an event after the status has been updated to pending" from model_spec.ts Registration via creation of control group suppose to work in a way

    builder.group({login: ["",Validators.required,validationFuctionWhichReturnsPromise]
    

    I spent a full evening to discovered that this code has been released in alfa-46 (and I used alfa-45) and after update depencies the async validation started to work. The feature is very fresh and is not fully documented but

    (for those who haven't tried it yet) Basically async validator is a function which have a Control argument and return a promise which validation result. There are two ways to register a validator. 1) the one which I used in my example and 2) as a directive which Provide validators via NG_ASYNC_VALIDATORS (See UniqLoginValidator and NgFormControl to see how it work). You can compose more than one validator (not tested yet but functions to do this are in code, see https://github.com/angular/angular/commit/cf449dd).

    But when I finally reach to up and running validators a new problem arrived. Async validator is perfect to used it in server side validation. But the validation is invoked after each change of model.fe after each keyup. So if we will send request to a server after each key up, it won't be too efficient way ;) I checked how it is done in angular 1 and they is a possibility to debouce validation events.

    My questions are:

    1. How to implement throttle or debouce with async validators? I saw some ideas but none of them were fine (mostly because they need to change angular code itself). Is there any valid way to do this without waiting for new angular release ?

    I was thinking about to warping a validator function with debouce (from underscorejs) but it will not work because angular expects to get a valid promise every time.

    My second though was that if all event use RxJs under the hood then maybe I can apply debouce on stream of event which is responsible for validation. In model.ts the promise returned from validator is change to observable and a new subscribed is added. We don't have any access to obs(Observable) to apply debouce there.

    1. Is there any way or id to change,easy extend a control over the form validation ?

    I spotted a close related problem in How to trigger Form Validators in angular2

    PS there is other issue related to async validators and it is still open https://github.com/angular/angular/issues/1068

    解决方案

    Here is a helper class that you can use to debounce all your async validators:

    import {Component} from 'angular2/core';
    import {Observable} from 'rxjs/Observable';
    import {Observer} from 'rxjs/Observer';
    import 'rxjs/add/operator/debounceTime';
    import 'rxjs/add/operator/distinctUntilChanged';
    import {Control} from 'angular2/common';
    
    export class AsyncValidator {
    _validate;
    
    constructor(validator: (control: Control) => any, debounceTime = 1000) {
        let source: any = new Observable((observer: Observer<Control>) => {
            this._validate = (control) => observer.next(control);
        });
    
        source.debounceTime(debounceTime)
            .distinctUntilChanged(null, (x) => x.control.value)
            .map(x => { return { promise: validator(x.control), resolver: x.promiseResolver }; })
            .subscribe(
                (x) => x.promise.then(resultValue => x.resolver(resultValue),
                (e) => { console.log('async validator error: %s', e); }));
    }
    
    private _getValidator() {
        return (control) => {
            let promiseResolver;
            let p = new Promise((resolve) => {
                promiseResolver = resolve;
            });
            this._validate({ control: control, promiseResolver: promiseResolver });
            return p;
        };
    }
    
    static debounce(validator: (control: Control) => any, debounceTime = 400) {
        var asyncValidator = new this(validator, debounceTime);
        return asyncValidator._getValidator();
    }
    }
    

    Then all you have to do where use async validators is just wrap your validator with this call and write your validator the same as you would normally:

    AsyncValidator.debounce(control => this.asyncValidator(control));
    

    Here is an example usage:

    export class AppComponent {
    form: ControlGroup;
    
    constructor(private _formBuilder: FormBuilder) {
        var validator = AsyncValidator.debounce(control => this.asyncValidator(control));
    
        this.form = _formBuilder.group({
            name: ['', Validators.required, validator],
        });
    }
    
    asyncValidator(control): any {
        let p = new Promise(resolve => {
            // get from server information need to validate control
    
            if (control.value === 'valid value') {
                resolve(null);
            } else {
    
                resolve({
                    asyncValidator: {
                        valid: false
                    }
                });
            }
        });
        return p;
    }
    }
    

    这篇关于一般:在angular2 asynchonious验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆