如何在Angular2中的去抖时间后触发验证输入?

时间:2016-02-08 19:59:21

标签: validation asynchronous angular

我有一个带有"名称"控制。

<div class="field">
  <label>Name</label>
  <input ngControl="name">
  <p *ngIf="name.pending">
    Fetching data from the server...
  </p>
  <div *ngIf="!name.valid && !name.pending"
    class="ui error message">Name is not valid</div>
</div>

该控件是使用FormBuilder构建的,如下所示:

this.name = fb.control('', null, this.characterNameValidator.bind(this));

我创建了一个验证器:

characterNameValidator(control: Control) {
    let q = new Promise((resolve, reject) => {
        setTimeout(() => {
            if (this._characterService.isCharacterNameAlreadyExists(control.value)) {
                resolve({nameCharacterAlreadyExistsError: true});
            } else {
                resolve(null);
            }
        }, 1000)
    });

    return q;
}

在每次击键时,我的验证器被调用。我正在寻找一种只在去抖时间之后调用验证器的方法。

我尝试使用valueChanges(),但我理解的只是在调用特定服务但不在验证的情况下。

修改

手动管理验证以实现我的问题是一个好主意吗?我没有在我的控件中放置验证器,但是我在valueChanges上手动设置了错误。

this.name = fb.control('');

this.name.valueChanges.debounceTime(400).subscribe(() => {
  this.characterNameValidator(this.name).then((validationResult => {
    this.name.setErrors(validationResult)
  }))
});

2 个答案:

答案 0 :(得分:2)

请参阅https://github.com/angular/angular/issues/1068了解相关的未解决问题。

如果您将对控件的引用传递给验证器,则可以使用类似

的内容
this.formGp.controls['numberFld'].updateValueAndValidity();

来自https://stackoverflow.com/a/33377290/217408

答案 1 :(得分:1)

获得所需内容的官方方式是即将推出的功能,以形成验证。

https://youtu.be/kM5QBOWrUVI?t=9m48s

但是,您可以通过订阅值更改并设置自己的错误来手动退出验证。

testForm.controls['name'].valueChanges
.do(
    res => {
        if (res) {
            this.testForm.controls['name'].setErrors({loading: true});
        }
    }
)
.debounceTime(500)
.subscribe(
    res => {
        if (this.nameSub) {
            this.nameSub.unsubscribe();
            this.nameSub = null;
        }

        this.nameSub = this.http.get(apiURL + 'exist/?name=' + res).subscribe(
            exists => {
                this.testForm.controls['name'].setErrors({nameExists: true});
                this.nameSub.unsubscribe();
                this.nameSub = null;
            },
            error => {
                if (res) {
                    this.testForm.controls['name'].setErrors(null);
                }
                this.nameSub.unsubscribe();
                this.nameSub = null;
            }
        );
    },
    error => {}
);