一般:Angular2 中的异步验证

2024-03-08

从几个晚上开始,我就开始在 augular2 中进行表单验证。

所有基本案例都很容易实现并且工作正常,但我坚持使用异步验证。我创建了一个非常小的例子http://plnkr.co/edit/Xo8xwJjhlHkXrunzS8ZE http://plnkr.co/edit/Xo8xwJjhlHkXrunzS8ZE但它不起作用。

根据 model_spec.ts 的测试,“状态更新为挂起后应该触发一个事件”,通过创建控制组进行注册,假设可以以某种方式工作

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

我花了整整一个晚上才发现这段代码已经在 alfa-46 中发布了(我使用了 alfa-45),并且在更新依赖项后,异步验证开始工作。该功能非常新鲜,尚未完整记录,但

(对于那些还没有尝试过的人)基本上,异步验证器是一个具有 Control 参数并返回验证结果的承诺的函数。注册验证器有两种方法。 1) 我在示例中使用的那个,2) 作为通过 NG_ASYNC_VALIDATORS 提供验证器的指令(请参阅 UniqLoginValidator 和 NgFormControl 了解它是如何工作的)。您可以编写多个验证器(尚未测试,但执行此操作的函数在代码中,请参阅https://github.com/angular/angular/commit/cf449dd https://github.com/angular/angular/commit/cf449dd).

但当我最终启动并运行验证器时,一个新问题出现了。异步验证器非常适合在服务器端验证中使用。但是每次 keyup 之后 model.fe 的每次更改都会调用验证。因此,如果我们在每次按键后向服务器发送请求,这不会是太有效的方式;)我检查了它是如何在角度1中完成的,它们有可能消除验证事件。

我的问题是:

  1. 如何使用异步验证器实现节流或反跳?我看到了一些想法,但没有一个很好(主要是因为它们需要更改角度代码本身)。有没有有效的方法可以做到这一点,而无需等待新的角度发布?

我正在考虑使用 debounce (来自 underscorejs)来扭曲验证器函数,但它不会工作,因为 Angular 期望每次都能得到有效的承诺。

我的第二个想法是,如果所有事件在幕后都使用 RxJs,那么也许我可以在负责验证的事件流上应用去抖动。在 model.ts 中,从验证器返回的 Promise 更改为可观察的,并添加了新的订阅。我们无法访问 obs(Observable) 来在那里应用去抖。

  1. 有什么方法或 ID 可以更改,轻松扩展对表单验证的控制吗?

我发现了一个密切相关的问题如何在 angular2 中触发表单验证器 https://stackoverflow.com/questions/32260082/how-to-trigger-form-validators-in-angular2

PS 还有其他与异步验证器相关的问题,但仍处于开放状态https://github.com/angular/angular/issues/1068 https://github.com/angular/angular/issues/1068


这是一个帮助器类,您可以使用它来消除所有异步验证器的反跳:

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();
}
}

然后,在使用异步验证器时,您所要做的就是用此调用包装您的验证器,并像平常一样编写验证器:

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

这是一个示例用法:

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;
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一般:Angular2 中的异步验证 的相关文章

随机推荐

  • Azure Functions - 导入自定义节点模块

    我正在尝试使用 Azure Functions 我正在尝试在我的函数中使用第三方节点模块 但是 我一直无法弄清楚如何导入它 id aaaaaaaa bbbb cccc dddd eeeeeeeeeeee requestId aaaaaaaa
  • Django 测试:测试表单字段的初始值

    我有一个观点 应该根据 GET 值为表单字段设置初始值 我想测试一下 我目前正在使用Django的测试客户端 http docs djangoproject com en dev topics testing module django t
  • 是否有命令行的版本控制系统抽象?

    现在 如此多的小型开源项目通过其版本控制系统 发布 我有数十个经常需要的存储库 通常位于多台计算机上 我正在寻找某种方法来轻松管理这个问题 如果我自己设计它 我将有一个列出所有远程存储库的文件 以及一个自动从它们中提取的命令行客户端 这个或
  • Express & Handlebars 的全球属性

    我使用 Handlebars 使用express3 handlebars 作为模板 使用 Passport 在 NodeJS 应用程序中进行身份验证 一切都很好 但我想知道是否有一种方法可以将 Passport 创建的 req user 对
  • 准备卸载,就像 Inno Setup 中的准备安装页面一样

    我需要检查多个 exe 文件是否正在运行 通过安装程序安装 然后提示用户关闭它们 如果它们正在运行 如果没有则取消卸载过程 有没有办法在安装中为卸载程序提供类似 准备 页面之类的内容 或者我该如何实施这样的检查 甚至一个消息框也将是完美的
  • Shapefile 到 TopoJSON 转换问题

    I m trying to convert a shapefile to GeoJSON and then to TopoJSON as described in Let s Make a Map http bost ocks org mi
  • 删除最后一次出现的字符

    A 今天在 talkstats com 上发现了这个问题 http www talkstats com showthread php 36897 regular expressions其中发布者想要使用正则表达式删除字符串的最后一个句点 而
  • 刷新jsp文件时线程锁定

    在重负载下 当 GZipping 和解压缩 JSP 文件时 我看到很多线程被锁定 线程转储如下所示 似乎来自大小为 14Kb 的 header jsp http 0 0 0 0 8080 304 daemon prio 3 tid 0x00
  • ASP.NET 页面上的 MS SQL 超时,但 SSMS 中没有

    当存储过程在我们的 ASP NET 页面之一上执行时 它在 SQL Server 上超时 但出现异常Timeout expired The timeout period elapsed prior to completion of the
  • 在 Python 中使用带有正则表达式的 OR 语句时防止列表中出现空元素

    我正在使用正则表达式从网站编译价格 PriceFinder re compile lt n s b d d 2 lt lt FF0000 gt b d d 2 lt Price re findall PriceFinder str soup
  • Cypher - 删除具有特定值的所有属性

    我正在寻找一种方法来删除数据库中任何节点的每个属性 使用 Cypher 具有特定值 Context我从关系表中获取了一个包含大量 NULL 值的 csv 批量文件 LOAD CSV将它们作为价值观 删除它们 用 csv 文件中的空 替换它们
  • 使用 ssh 检查远程主机上是否存在文件

    我想检查远程主机上是否存在某个文件 我试过这个 if ssh user localhost p 19999 e home user Dropbox path Research and Development Puffer and Traps
  • SQLSRV PHP for SQL Server 不是有效的 Win32 应用程序

    这是我的设置 Windows Server 2008 R2 64 位 阿帕奇 2 4 4 64 位 PHP 5 4 15 32位 64位仍处于实验阶段 线程安全 VC9编译器 Microsoft SQL Server 2012 本机客户端
  • 锚元素的 ping 属性跨浏览器如何?

    a 是 HTML5 锚元素中一个相对较新 相对未知的属性 它的跨浏览器兼容性如何 我查看了 MDN 等在线资源http caniuse com http caniuse com 但没有发现任何表明浏览器支持的信息 我想知道这是否是 2014
  • 在docker中安装.net框架4.7.2

    我是 Net 环境的新手 我正在尝试为我的公司实施 docker 他们之前使用的是 4 5 所以我在 dockerfile 中使用了以下语句 RUN Install WindowsFeature NET Framework 45 ASPNE
  • 如何设置Spark执行器内存?

    我已经设定Spark executor 内存 to 2048m 并且在 UI 环境 页面中 我可以看到该值已正确设置 但是在 Executors 页面中 我看到只有1个执行器 它的内存是265 4MB 非常奇怪的价值 为什么不是256MB
  • const char* 连接

    我需要连接两个 const 字符 如下所示 const char one Hello const char two World 我该怎么做呢 我通过了这些char 来自具有 C 接口的第三方库 所以我不能简单地使用std string反而
  • 显示所有 messageHeader 的值

    我想知道显示所有 MessageHeaders 服务器端的最佳方式是什么 实际上我知道的唯一方法如下 OperationContext Current IncomingMessageHeaders GetHeader
  • 将 Powershell 核心设置为 Windows/Linux 上的默认 GNU Make shell

    在 Windows 上的 makefile 中 使用以下 make 版本 PS C projects gt make version GNU Make 4 1 Built for i686 w64 mingw32 Copyright C 1
  • 一般:Angular2 中的异步验证

    从几个晚上开始 我就开始在 augular2 中进行表单验证 所有基本案例都很容易实现并且工作正常 但我坚持使用异步验证 我创建了一个非常小的例子http plnkr co edit Xo8xwJjhlHkXrunzS8ZE http pl