简体   繁体   English

Angular 4-使用异步自定义验证器

[英]Angular 4 - Using Asynchronous custom validators

I have the following code: 我有以下代码:

HTML: HTML:

<div [class]="new_workflow_row_class" id="new_workflow_row">
    <div class="col-sm-6">
        <label class="checkmark-container" i18n>New Workflow
            <input type="checkbox" id="new-workflow" name="new-workflow" [(ngModel)]="new_checkbox" (click)="uncheckBox($event, 'edit')"> 
            <span class="checkmark" id="new-workflow-checkmark" [class]="checkmark_class"><span id="new-workflow-checkmark-content"></span>{{checkmark_content}}</span>
        </label>
        <input type="text" *ngIf="new_checkbox" id="new_workflow_name" name="new_workflow_name" (keyup)="clearWorkflowError(true)" [(ngModel)]="new_workflow" placeholder="Enter Workflow Name">
        <p [hidden]="!show_workflow_error && !workflowForm.errors" class="workflow-error" i18n>The workflow name already exists. Please use a different name.</p>
    </div>
</div>

Component.ts: Component.ts:

duplicateWorkflowValidator(control: FormControl) {
    console.log("this validator was called!");
    clearTimeout(this.workflowTimeout);

    return new Promise((resolve, reject) => {
        if (this.new_workflow != '') {
            this.workflowTimeout = setTimeout(() => {
                this
                    .requestService
                    .findWorkflow(control.value)
                    .subscribe((results: any) => {
                        let data: any = results.data;

                        if (data.duplicate) {
                            resolve({ duplicateWorkflow: { value: control.value}})
                        }
                        else if (results.status == "OK") {
                            resolve(null);
                        }
                    })
                ;
            }, 500);
        }
        else {
            resolve(null);
        }


    })

}

Inside constructor for component.ts: 在component.ts的内部构造函数中:

this.workflowForm = new FormGroup({
    name: new FormControl(this.new_workflow, [
        Validators.required,
    ], this.duplicateWorkflowValidator.bind(this))
});

I am trying to bind this asynchronous validator to the reactive form but it's not working. 我正在尝试将此异步验证器绑定到反应形式,但是它不起作用。 I want to use the duplicateWorkflowValidator inside workflowForm and have it trigger an error message when it finds a duplicate workflow. 我想在工作流程窗体内使用plicatorWorkflowValidator,并在找到重复的工作流程时触发错误消息。

How do I a) bind the validator to the reactive form properly, b) access the validator errors? 我如何a)正确地将验证器绑定到反应形式,b)访问验证器错误? Thanks in advance, hopefully this makes sense. 预先感谢,希望这是有道理的。

You are mixing template forms with reactive forms. 您正在将模板形式与反应形式混合在一起。 Chose one approach. 选择一种方法。 In the below example I am using reactive forms. 在下面的示例中,我使用了反应形式。

Try this simplified version. 试试这个简化版本。 For demonstration purposes below the validator will fail when I type test , but succeed when I type anything else. 出于演示目的,当我键入test ,验证器将失败,但是当我键入其他任何内容时,验证器将成功。 You will need to change that to your service call. 您需要将其更改为服务电话。

https://angular-sjqjwh.stackblitz.io https://angular-sjqjwh.stackblitz.io

Template: 模板:

<form [formGroup]="myForm">
    <div>
        <div>
            <input type="text" formControlName="name">
            <div *ngIf="myForm.controls.name.hasError('duplicateWorkflow')">
                Workflow already exists!
            </div>
            {{ myForm.controls.name.hasError('duplicateWorkflow') | json }}
        </div>
    </div>
</form>

Component 零件

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators, Form, FormBuilder } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  workflowTimeout: number = 0;
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      name: new FormControl('', 
        [Validators.required], 
        this.duplicateWorkflowValidator.bind(this))
    });
  }

  duplicateWorkflowValidator(control: FormControl) {
    console.log("this validator was called!");

    return new Promise((resolve, reject) => {
      if (control.value === 'test') {
        this.workflowTimeout = setTimeout(() => {
          resolve({ duplicateWorkflow: { value: control.value } })
        }, 500);
      }
      else {
        resolve(null);
      }
    });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM