这是我的LoadingScreenService:
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
import { NavigationStart, NavigationEnd, Router, NavigationCancel } from '@angular/router';
@Injectable()
export class LoadingScreenService {
private loadingScreenEl: HTMLElement = null;
private player: AnimationPlayer;
private isEnabled = false;
private isShowing = false;
private isHiding = false;
constructor(
private animationBuilder: AnimationBuilder,
@Inject(DOCUMENT) private document: any = null,
private router: Router = null
) {
if (document !== null) {
this.loadingScreenEl = this.document.body.querySelector('#fuse-loading-screen');
}
if (router !== null) {
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
setTimeout(() => {
this.show();
}, 0);
}
if (event instanceof NavigationEnd || event instanceof NavigationCancel) {
setTimeout(() => {
this.hide();
}, 0);
}
}
);
}
}
/**
* @param {number} wait Duration (ms) of a timeout before showing the spinner
*/
show(wait: number = 1000) {
if (this.isEnabled || this.isShowing) {
return;
}
this.isShowing = true;
this.player =
this.animationBuilder
.build([
style({
opacity: '0',
zIndex : '9999'
}),
animate('200ms ease', style({opacity: '1'}))
]).create(this.loadingScreenEl);
this.isEnabled = true;
setTimeout(() => {
this.player.play();
setTimeout(() => {
this.isShowing = false;
}, 200);
}, wait);
}
hide() {
if (!this.isShowing
&& (!this.isEnabled || this.isHiding)) {
return;
}
this.isHiding = true;
this.player =
this.animationBuilder
.build([
style({opacity: '1'}),
animate('200ms ease', style({
opacity: '0',
zIndex : '-20'
}))
]).create(this.loadingScreenEl);
setTimeout(() => {
this.isEnabled = false;
this.player.play();
setTimeout(() => {
this.isHiding = false;
}, 200);
}, 0);
}
}
每当我向后端发出请求时,我都会尝试使用show / hide方法。
这是我到目前为止所得到的,但我找不到一种方法将我的subscriveLoading()方法正确地放入intercept()。
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { LoadingScreenService } from '../../core/services/loading-screen.service';
@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
constructor(
private loadingScreenService: LoadingScreenService
) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
}
private subscribeLoading(): Observable<any[]> {
this.loadingScreenService.show();
const observable;
observable.subscribe(() => {
this.loadingScreenService.hide();
}, err => {
this.loadingScreenService.hide();
return err;
}); // Pass the error to other observers
return observable;
}
}
我是否有一些简单的方法可以使用我的LoadingScreenService来拦截每个调用,并在我等待来自后端的响应时使用show方法提供的服务?
答案 0 :(得分:2)
这是一种在拦截器中使用您的服务的方法
在拦截中你开始显示你的加载器,然后你的intecept返回一个finally操作符的请求,该操作符将隐藏成功或错误
@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
constructor(
private loadingScreenService: LoadingScreenService
) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loadingScreenService.show();
return next.handle(req).finally(() => {
this.loadingScreenService.hide();
});
}
}
但是:如果你有两个并发请求,当第一个请求结束时,即使第二个请求没有完成,它也会隐藏加载器。
您的服务中应该有待处理请求的计数器:
@Injectable()
export class LoadingScreenService {
....
private counter: number: 0;
...
show(wait: number = 1000) {
this.counter++;
....
}
hide() {
this.counter--;
if (this.counter > 0) return;
...
}