je suis nouveau sur angular 5. Comment coder une fonction commune pour afficher le spinner pour chaque requête HTTP en angular 5.Veuillez m'aider à l'implémenter).
Vous pouvez utiliser Angular HttpInterceptor pour afficher un spinner pour toutes vos demandes, voici un bon article moyen sur la façon de mettre en œuvre un intercepteur http
De plus, vous devrez créer un service/module spinner et l'injecter dans votre intercepteur http. Enfin, dans votre méthode d'interception, vous pouvez utiliser la méthode finally
rxJs pour arrêter votre spinner. Voici une implémentation simple:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinnerService.start();
return next.handle(req).finally(res => this.spinnerService.stop() );
}
Prendre plaisir!
Bonus: voici un exemple d'implémentation du service spinner
Cela n'a rien à voir avec les requêtes HttpClient ou HTTP. Il s'agit de savoir comment gérer les appels asynchrones en général (HTTP ou non).
Tu aurais dû
<div class="spinner" *ngIf="loading"; else showWhenLoaded"><div>
<ng-template #showWhenLoaded>
<div>Your Content</div>
</ng-template>
et dans le fichier ts:
loading: boolean = true;
methodToTriggerRequest() {
this.loading = true;
this.http.get(...).subscribe(response => {
if (resposnseNotAnError(response)) {this.loading = false}
})
}
Le guide complet est ici avec un matériau mat-progress-spinner
utilisation. Très cool!
Source Lien
Créer un service
//loader.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class LoaderService {
public isLoading = new BehaviorSubject(false);
constructor() { }
}
Créer un intercepteur de chargeur
// loader.interceptors.ts
import { Injectable } from '@angular/core';
import {
HttpErrorResponse,
HttpResponse,
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { LoaderService } from './loader.service';
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
private requests: HttpRequest<any>[] = [];
constructor(private loaderService: LoaderService) { }
removeRequest(req: HttpRequest<any>) {
const i = this.requests.indexOf(req);
if (i >= 0) {
this.requests.splice(i, 1);
}
this.loaderService.isLoading.next(this.requests.length > 0);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.requests.Push(req);
console.log("No of requests--->" + this.requests.length);
this.loaderService.isLoading.next(true);
return Observable.create(observer => {
const subscription = next.handle(req)
.subscribe(
event => {
if (event instanceof HttpResponse) {
this.removeRequest(req);
observer.next(event);
}
},
err => {
alert('error returned');
this.removeRequest(req);
observer.error(err);
},
() => {
this.removeRequest(req);
observer.complete();
});
// remove request from queue when cancelled
return () => {
this.removeRequest(req);
subscription.unsubscribe();
};
});
}
}
Maintenant, créez un composant de chargeur, puis ajoutez le composant d'application
//loader.interceptor.ts
import { Component, OnInit } from '@angular/core';
import { LoaderService } from '../loader.service';
@Component({
selector: 'app-loading',
templateUrl: './loading.component.html',
styleUrls: ['./loading.component.css']
})
export class LoaderComponent implements OnInit {
loading: boolean;
constructor(private loaderService: LoaderService) {
this.loaderService.isLoading.subscribe((v) => {
console.log(v);
this.loading = v;
});
}
ngOnInit() {
}
}
Vous pouvez créer un service, puis y publier des événements au niveau racine de l'application qui y est abonnée. Laisse-moi expliquer.
broadcast.service.ts (c'est votre service)
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/filter'
import 'rxjs/add/operator/map'
/**
* This class acting as event service bus for the entire app.
* No Need to register the class as this registered in the root level.
* Can just inject to componets.
*/
@Injectable()
export class BroadcastService {
private _handler: Subject<Message> = new Subject<Message>();
broadcast(type: string, payload: any = null) {
this._handler.next({ type, payload });
}
subscribe(type: string, callback: (payload: any) => void): Subscription {
return this._handler
.filter(message => message.type === type)
.map(message => message.payload)
.subscribe(callback);
}
}
interface Message {
type: string;
payload: any;
}
Ensuite, vous pouvez publier et vous abonner à des événements comme celui-ci:
votre niveau de service:
this.broadcastService.broadcast('PROGRESS_START');
Au niveau du composant de votre application:
this.broadcastService.subscribe('PROGRESS_START', ()=>{
//hit when you start http call
this.myLoader = true;
});
enfin dans app.component.html:
<div *ngIf="myLoader">
<!--YOUR LOADER SHOULD GO HERE-->
</div>
<router-outlet></router-outlet>
Il s'agit d'un moyen très générique à couplage lâche d'implémenter le chargeur de votre choix.