0

Je crée une typeahead qui appelle à distance une API à chaque fois que quelqu'un saisit l'entrée, avec un petit délai après la saisie. Ce code est de bootstrap 4 typeahead example docs (Wikipedia example). Cela n'a aucun sens avec toutes les fonctions .call et _do.Réécriture d'une séquence observable pour avoir plus de sens

composante angulaire

import { map } from 'rxjs/operator/map'; 
import { debounceTime } from 'rxjs/operator/debounceTime'; 
import { distinctUntilChanged } from 'rxjs/operator/distinctUntilChanged'; 
import { _catch } from 'rxjs/operator/catch'; 
import { _do } from 'rxjs/operator/do'; 
import { switchMap } from 'rxjs/operator/switchMap'; 

search = (text$: Observable<string>) => 
    _do.call(
    switchMap.call(
     _do.call(distinctUntilChanged.call(
      debounceTime.call(text$, 300)), 
      () => this.searching = true), 
      (term) => _catch.call(
       _do.call(this._service.search(term), 
      () => this.searchFailed = false), 
      () => { 
       this.searchFailed = true; 
       return of.call([]); 
     })), 
    () => this.searching = false); 

HTML

 <md-input-container> 
     <input mdInput [ngbTypeahead]="search" 
      [(ngModel)]="model" 
      [formControl]="lookupSubscriberControl" 
      type="text" 
      placeholder="Search by Name"> 
     <button type="submit" mdSuffix class="material-icons">search</button> 
    </md-input-container> 

1) Qu'est-ce que cela fait en anglais? À l'heure actuelle, je ne comprends pas comment lire ceci en termes normaux et je ne peux donc pas le réécrire pour mes besoins.

2) Quelqu'un peut-il m'aider à le réécrire dans un format plus lisible? Tels que l'utilisation de la séquence enchaînée des promesses, ou toute autre chose qui a plus de sens.

Répondre

3

Je suis d'accord que cela semble un peu torturé. Je suppose que cela a été fait puisqu'ils importent le operators directement plutôt que d'utiliser les variantes add/ pour ajouter les opérateurs au prototype Observable.

En gros, si nous devions réécrire ce que nous voyons traditionnellement Observables il ressemblerait à ceci:

search = (text$: Observable<string>) => 
    text$.debounceTime(300) 
    .distinctUntilChanged() 
    .do(() => this.searching = true) 
    .switchMap(term => 
    this._service.search(term) 
     .do(() => this.searchFailed = false) 
     .catch(() => { 
     this.searchFailed = true; 
     return Observable.of([]); 
     }) 
    ) 
    .do(() => this.searching = false); 

Notez que vous aurez également besoin de changer aussi les importations pour les opérateurs, de sorte qu'ils sont ajoutés à la prototype observable:

import 'rxjs/add/operator/debounceTime'; 
import 'rxjs/add/operator/distinctUntilChanged'; 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/switchMap'; 

Fondamentalement tout ce qu'il fait reçoit une observable de requêtes de recherche dont il est debouncing, de sorte que les demandes ne sont pas faites avec des données périmées, il supprime en double requêtes consécutives. Ensuite, il utilise les blocs do pour appliquer certains effets secondaires qui seront vraisemblablement reflétés dans l'interface utilisateur. Et finalement, il fait une requête pour chaque requête qui traite la requête de recherche et renvoie un tableau de résultats. Si quelque chose ne va pas, il attrape l'état d'échec et les ensembles et les erreurs avant de retourner un tableau de données vide.

+0

Magnifique! Merci, c'est exactement ce que je cherchais. – TetraDev