2016-10-20 10 views
1

Eigentlich steckte ich in diesem Problem.Angular 2 Async Form Validator

Ich habe einen benutzerdefinierten Async-Validator erstellt, um zu überprüfen, ob ein Benutzername vergeben wurde oder nicht. Dies ist, wo ich es binden:

'name': ['',[Validators.required, Validators.minLength(4), Validators.minLength(4)], this.asyncName.bind(this)], 

Und das ist mein Validator:

asyncName(control: FormControl) { 
    this.names$ = this.af.database.list('/usernames') 
    .map (name => { 
      name.filter(name => { 
       if (name.name.toLowerCase() === control.value.toLowerCase()) { 
        console.log("Username taken"); 
        return { 
         valid: false 
        }; 
       } else { 
        console.log("Username available"); 
        return { 
         valid: true 
        }; 
       } 
      }) 
     });    

    return this.names$; 
}; 

So diese Prüfung funktioniert. Wenn der Benutzername vergeben ist, wird "Benutzername vergeben" oder "Benutzername verfügbar" protokolliert.

Mein Problem: Die Rückgabeanweisung funktioniert nicht. Wenn ich den Status des Formulars abonniere, wäre es immer noch "Ausstehend" und nicht "Gültig" oder "Ungültig". Angular2 denkt, dass die Validierung noch läuft.

Kann jemand eine gültige Rückgabe- oder Auflösungsanweisung basierend auf Observablen erstellen?

Vielleicht, um mich selbst zu abonnieren und etwas mit der Funktion resolve() zu tun. Aber alle meine Versuche haben nicht funktioniert.

Vielen Dank im Voraus !!!

Antwort

3

Sie können .first() versuchen, die beobachtbare schließt nach der ersten Veranstaltung zu gewährleisten:

asyncName(control: FormControl) { 
    this.names$ = this.af.database.list('/usernames').first() 
    .map(... 

Nicht sicher, ob dies das eigentliche Problem ist.

0

Ich hatte ähnliches Problem. In meinem Fall hatte ich Kategorienliste und ich wollte überprüfen, ob ein Kategoriename eindeutig ist oder nicht. Das ist mein Validator:

export class CategoryFormComponent { 
 
    constructor(
 
    private firebase: AngularFireDatabase 
 
) {} 
 
    
 
    categoryExists(control: AbstractControl) { 
 
    return this.firebase.database 
 
     .ref(`categories/${this.uid}`) // user's uid 
 
     .orderByChild('name') 
 
     .equalTo(control.value) 
 
     .once('value') 
 
     .then((snapshot) => { 
 
      return snapshot.val() ? { categoryExists: true } : null; 
 
     }); 
 
    } 
 
}

Wie Sie sehen können Sie Suche auf Datenbank (mehr performant) machen und dann verwenden einmal die Renditen versprechen.

Verwandte Themen