2017-02-06 4 views
2

Ich muss allgemeine Loader in gesamten angular2 Projekt einrichten. Also ich möchte nur tun, wenn meine neue http Aufruf entweder GET, POST oder PUT generieren, dann bevor Anfrage gesendet Loader angezeigt wird. Sobald http Antwort (Erfolg oder Fehler) von der Serverseite ankommen, dann sollte Loader verschwinden.Aufruf der gemeinsamen Funktion vor und/oder nach HTTP-Anfrage in Winkel 2

Es gibt irgendein eingebautes Modul, das verfügbar ist, dass ich oben genannte Funktionalität tun kann. Oder gib mir einen Weg, damit ich es mit eckigen Funktionen machen kann. Ich verwende rxjs für http Anfrage.

Ich möchte nicht jQuery oder Javascript verwenden.

Antwort

2

Erstellen Sie http Interceptor und rufen Sie Ihre gemeinsamen Funktionen in ihm. Sie können entweder eigene Interzeptorimplementierung schreiben like this oder an external library

1
@Injectable() 
class MyService { 
    private change:Subject<boolean> = new BehaviorSubject(false); 
    public change$ = this.change.asObservable(); 

    constructor(private http:Http) {} 

    get(...) { 
    this.change.next(true) 
    return this.http.get(...) 
    .map(...) 
    .finally(_ => this.change.next(false); 
    } 
} 
@Component({ 
    selector: 'loader', 
    template: ` 
    <div *ngIf="myService.change | async">is loading ...</div> 
` 
)} 
class LoaderComponent { 
    constructor(public myService:MyService){} 
} 
2

verwenden HTTP Erweiterung funktioniert gut - in unserem Projekt, das wir auch explizite Kontrolle des ‚loader‘ aka Spinner für einige Szenarien wollte. So haben wir eine SpinnerService in unserem Core module, die für alle Komponenten verfügbar ist.

@Injectable() 
export class SpinnerService { 

    private spinnerStateSource = new Subject<SpinnerState>(); 
    spinnerState$ = this.spinnerStateSource.asObservable(); 

    private defaultMessage: string = 'Loading...'; 

    show(message?: string) { 

    let msg = this.defaultMessage as string; 
    if (message) { 
     msg = message; 
    } 

    this.spinnerStateSource.next({ showing: true, message: msg }); 
    } 

    hide() { 
    this.spinnerStateSource.next({ showing: false, message: '' }); 
    } 

    spin(obs: Observable<any>, message?: string): Observable<any> { 
    this.show(message); 
    return obs.finally(() => this.hide()); 
    } 

} 

class SpinnerState { 
    showing: boolean; 
    message: string; 
} 

Eine Komponente in dem Hauptmodul abonniert den Dienst anzuzeigen/den tatsächlichen Spinner UI (EDIT: genau wie in @ Gunter Antwort) verstecken und andere Komponenten können (über den Dienst), um die Spinner sagen zu zeigen, /verbergen.

Ein Beispiel, das wir verwenden, ist, wenn eine Komponente mehrere HTTP-Aufrufe an z. Holen Sie sich einige Referenzdaten, und wir möchten, dass der Spinner angezeigt wird, bis alle diese Aufrufe ausgeführt wurden. So rufen wir die spin-Funktion mit der Aktion, auf die wir warten, auf

z. in der Verbrauchskomponente:

this.spinnerService.spin(
    Observable.forkJoin(
     this.refDataService.getRefDataList('statusTypes'), 
     this.refDataService.getRefDataList('itemTypes') 
    ) 
).subscribe(result => { 
      this.statusTypes = result[0]; 
      this.itemTypes = result[1]; 
}); 
+0

Hier haben Sie 'SpinnerState' verwendet. Was ist der Standardwert? Ich habe einen Fehler, wenn ich diesen Code kopiere. Auch was ist 'spinnerState $'? – Jitendra

+0

Es ist ein Typ mit Informationen an den Spinner übergeben - Ich habe meine Post bearbeitet –

+0

Es funktioniert gut, aber ich muss diesen Dienst importieren, wo ich seine Methode verwenden. Irgendeine Möglichkeit, etwas gemeinsam zu machen? Wenn eine HTTP-Anfrage generiert wird, ruft sie automatisch die Methode 'spinnerService.spin' auf, so dass ich diese Methode nicht bei jeder Anfrage aufrufen muss. – Jitendra

Verwandte Themen