2017-12-05 2 views
0

Ich habe den folgenden Code:Angular 4 - Asynchrone benutzerdefinierten Validierer

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:

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


    }) 

} 

Innen Konstruktor für component.ts:

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

Ich versuche, t zu binden sein asynchroner Validator für die reaktive Form, aber es funktioniert nicht. Ich möchte den duplicateWorkflowValidator innerhalb von workflowForm verwenden und eine Fehlermeldung auslösen, wenn ein doppelter Workflow gefunden wird.

Wie kann ich a) den Validator korrekt an die reaktive Form binden, b) auf die Validatorfehler zugreifen? Danke im Voraus, hoffentlich macht das Sinn.

+0

Ihr Code sieht richtig. Haben Sie einen Fehler? –

+0

Ja, die Validierungsfehler geben mir den "erforderlichen" Fehler, auch wenn das Feld nicht leer ist. – janedoe

+0

Haben Sie versucht, den 'Debugger;' vor dem 'if' zu setzen und ihn zu durchlaufen? –

Antwort

1

Sie mischen Vorlagenformen mit reaktiven Formen. Wählen Sie einen Ansatz. Im folgenden Beispiel verwende ich reaktive Formen.

Versuchen Sie diese vereinfachte Version. Zu Demonstrationszwecken unten wird der Validator fehlschlagen, wenn ich test eintippe, aber gelingen, wenn ich irgendetwas anderes eintippe. Sie müssen dies zu Ihrem Serviceanruf ändern.

https://angular-sjqjwh.stackblitz.io

Vorlage:

<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> 

Komponente

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); 
     } 
    }); 
    } 
} 
Verwandte Themen