0

In meiner Angular App gibt es eine Seite von "Listings". Da es Hunderte von Auflistungen gibt, werden die Ergebnisse nur jeweils 20 geladen und weitere werden geladen, wenn der Benutzer nach unten scrollt und auf More klickt.Wie wird die asynchrone Typahead-Suche richtig implementiert?

Ich möchte ein Suchfeld oberhalb der Einträge platzieren, die einen spezifischeren Suchbegriff an den Server senden könnten, um nur übereinstimmende Einträge zurückzugeben.

Zum Beispiel, wenn der Benutzer „myterm“ in das Suchfeld eingibt, Angular sollten nur die Ergebnisse auf der „Anzeigen“ Seite ein GET-https://myapp.com/listings/?search=myterm und Anzeige senden.

Ich bin mir nicht sicher, was der richtige Weg, dies in Angular 2+ zu tun ist. In AngularJS hätte ich einfach eine neue Anfrage ausgelöst, die jedes Mal ein Versprechen zurückgibt Suche wurde gedrückt, aber ich vermute, Angular2 + hat einen anderen Ansatz. Ich kann einfach keine Literatur darüber finden.

Bisher habe ich mich sehr über den anfänglichen Funktionsaufruf in der Komponente, die den Dienst mit einem leeren Suchparameter nennt (auch bekannt als, alles bekommen)

ngOnInit() { 
    this.listings = this.listingService.getListings(''); 
} 

Antwort

1

ich ReactiveFormsModule verwenden empfehlen, da es wirklich sein werde einfach, dieses Problem zu lösen.

Zuerst definieren wir unsere FormGroup, die aus einem einzigen Formular Steuerelement bestehen wird.

form: FormGroup; 

constructor(formBuilder: FormBuilder){ 
    this.form = formBuilder.group({ 
     search: '' 
    }); 
} 

Jetzt, wo wir unser einfaches Formular definiert haben, was wir daran interessiert sind, wird eine Anfrage während der Benutzer tippt senden, so dass im Grunde, wenn der Wert unserer Formsteuerung geändert hat. Wir können auf die valueChanges Observable wie diese abonnieren:

ngOnInit(){ 
    this.form.get('search').valueChanges 
     .subscribe(value => this.listingService.getListings(value))); 
} 

Dies zeigt deutlich funktioniert, aber das Problem dabei ist, dass wir nicht wollen, gibt der Benutzer eine Anfrage für jedes einzelne Zeichen senden. Wir wollen warten bis er fertig ist. Wir können das Problem beheben, indem die debounceTime Operator:

this.form.get('search').valueChanges 
     .debounceTime(1000) 
     .subscribe(value => this.listingService.getListings(value))); 

wir auch switchMap Operator verwenden, um zu vermeiden, eine Kette von Abonnements vornehmen zu müssen (da getListings auch eine beobachtbare zurückgibt). Das letzte, was wir tun müssen, ist einen Filter hinzuzufügen, weil wir keine Anfrage mit einer leeren Zeichenfolge senden wollen, vorausgesetzt, der Benutzer löscht alles, was eingegeben wurde. Und wir haben die filter Betreiber dafür:

this.form.get('search').valueChanges 
     .filter(value => value) 
     .debounceTime(1000) 
     .switchMap(value => this.listingService.getListings(value)) 
     .subscribe(listings => this.listings = listings); 

Vorlage sollte ähnlich sein:

<form [formGroup]="form"> 
    <input type="text" formControlName="search"> 
</form> 
+0

Vielen Dank für die Antwort. Können Sie mir sagen, wie bekomme ich den Wert der Funktion "getListings" in die Eigenschaft "Listings", so dass es auf der Seite angezeigt werden kann. Beachten Sie, dass 'getListings' den Server aufruft und somit auch ein Observable zurückgibt. – CodyBugstein

+0

Und wie präsentiere ich dieses Formular in der Ansicht? – CodyBugstein

+0

Ich habe meine Antwort bearbeitet. Ich nahm an, dass du mit diesen Konzepten vertraut warst, also mein Schlechter. Wie auch immer, ich schlage vor, dass Sie die Dokumente lesen, um besser zu verstehen, was vor sich geht und damit Sie auch alles richtig importieren. – Christian

Verwandte Themen