angular - 我试图在请求完成时通知观察者以停止显示加载微调器
问题描述
我通过注入我创建的 loadIndicatorService 的拦截器拦截请求,它工作正常,但是当我在 ngOnInit 中加载用户时,LoadIndicator 将请求视为即时请求,代码如下:
@Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
constructor( private loadingIndicatorService: LoadingIndicatorService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loadingIndicatorService.onStarted(request);
const currentUser = localStorage.getItem('token');
request = request.clone({
url: `${environment.apiURL}/${environment.apiVersion}/${request.url}`,
setHeaders: {
'Content-Type': 'application/json',
Authorization: `Bearer ${currentUser}`
}
});
return next.handle(request).finally(() => this.loadingIndicatorService.onFinished(request));
}
}
和服务:
@Injectable({
providedIn: 'root'
})
export class LoadingIndicatorService {
onLoadingChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
/**
* Stores all currently active requests
*/
private requests: HttpRequest<any>[] = [];
/**
* Adds request to the storage and notifies observers
*/
onStarted(req: HttpRequest<any>): void {
this.requests.push(req);
this.notify();
}
/**
* Removes request from the storage and notifies observers
*/
onFinished(req: HttpRequest<any>): void {
const index = this.requests.indexOf(req);
if (index !== -1) {
this.requests.splice(index, 1);
}
this.notify();
}
/**
* Notifies observers about whether there are any requests on fly
*/
private notify(): void {
this.onLoadingChanged.emit(this.requests.length !== 0);
}
}
解决方案
我建议创建一个广播加载状态的服务,并且加载微调器组件会观察到该服务。每个操作/请求都将使用此服务更新加载状态。
一个例子:
@Injectable()
export class LoaderService {
private loaderSubject = new Subject<boolean>();
constructor() {}
show() {
this.loaderSubject.next(true);
}
hide() {
this.loaderSubject.next(false);
}
select(): Observable<boolean>{
return this.loaderSubject.asObservable();
}
}
微调器组件:
@Component({
selector: 'app-loader',
template: 'YOUR SPINNER'
})
/**
* Loader Component to show a spinner when the state's show equals to true
*
*/
export class LoaderComponent implements OnDestroy, OnInit {
show = false;
private subscription: Subscription;
constructor(private loaderService: LoaderService) {}
ngOnInit() {
this.subscription = this.loaderService.select().subscribe(
(state: boolean) => {
this.show = state;
}
);
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
}
你的拦截器:
@Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
constructor( private loader: LoaderService) { }
intercept(request: HttpRequest, next: HttpHandler): Observable> {
this.loadingIndicatorService.show();
const currentUser = localStorage.getItem('token');
request = request.clone({
url: `${environment.apiURL}/${environment.apiVersion}/${request.url}`,
setHeaders: {
'Content-Type': 'application/json',
Authorization: `Bearer ${currentUser}`
}
});
return next.handle(request).finally(() => this.loading.hide());
}
}
推荐阅读
- scala - “EntityStreamException:实体流截断”是否仅仅意味着客户端超时?
- html - 您可以在不嵌入的情况下在您的网站上显示 youtube 视频吗?
- mysql - 如何测试mysql插入方法
- java - 检查java中map的每个键作为空检查
- spring-boot - Spring Data JPA:java.sql.SQLException:找不到列“id”
- dotnetnuke - 从 DNN 9.0.1 升级到 DNN 9.0.2 时的 UpgradeWizard.aspx 错误
- c# - 启动在另一个项目时Controller找不到视图
- python - 可以使用 gensim Doc2Vec 将新文档与训练模型进行比较吗?
- sql - 工作日聚合的星期函数
- ckeditor - ckeditor balloonpanel在滚动时没有保持附着在元素上