我有带有加载条的组件,该加载条显示和隐藏名为isLoading
的布尔变量。例如:
ngOnInit() {
this.isLoading = true;
this.someService.getAll().subscribe(data => {
// some code...
this.isLoading = false;
});
}
<loading-bar *ngIf="isLoading"></loading-bar>
但是,当主组件中有子组件并且从中加载数据时,我有一个问题。加载栏应位于主组件中,并且仅在来自所有子组件的数据到达时才隐藏。实现此目标的最佳方法是什么。
答案 0 :(得分:2)
您可以使用HttpInterceptor来感知应用程序中正在进行的任何HTTP活动,并创建一个在其中保留HTTP活动标志的服务。现在,在您的根组件中,只需检查该标志并显示一个加载微调器即可。这样,您不必分别处理每个子组件和子组件的加载栏的显示。
HTTPInterceptor和相关服务的代码应如下所示。
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest
} from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
import { catchError, finalize, map } from 'rxjs/operators';
@Injectable()
export class HTTPStatus {
private requestInFlight$: BehaviorSubject<boolean>;
constructor() {
this.requestInFlight$ = new BehaviorSubject(false);
}
setHttpStatus(inFlight: boolean) {
this.requestInFlight$.next(inFlight);
}
getHttpStatus(): Observable<boolean> {
return this.requestInFlight$.asObservable();
}
}
@Injectable()
export class HTTPListener implements HttpInterceptor {
constructor(private status: HTTPStatus) {
}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
map(event => {
this.status.setHttpStatus(true);
return event;
}),catchError(error => {
return Observable.throw(error);
}),
finalize(() => {
this.status.setHttpStatus(false);
})
)
}
}
在您的根应用程序组件中注入HTTPStatus服务。
HTTPActivity: boolean;
constructor(private httpStatus: HTTPStatus) {
this.httpStatus.getHttpStatus().subscribe(status => { this.HTTPActivity = status; });
}
现在,在组件的.html部分中,您可以通过检查HTTPActivity布尔变量来显示/隐藏加载栏或微调器。
<div id="preloader" [hidden]=!HTTPActivity>
<div id="loader"></div>
</div>
当然,您必须在模块的providers数组中注册HTTPListener和HTTPStatus服务。
谢谢。
答案 1 :(得分:1)
您可以为每个子组件创建isLoaded标志。 然后,通过服务共享标记状态到您的父组件。父组件的isLoaded标志将是孩子的isLoaded的组合
答案 2 :(得分:1)
我们放在整个应用程序本身上的装载程序不是吗?
您需要“实现” HttpInterceptor并在其中使用加载器,方法是将这两者与加载器服务一起附加。
这是HttpInterceptor的示例实现。
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
constructor(public loaderService: LoaderService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loaderService.show();
return next.handle(req).pipe(
finalize(() => this.loaderService.hide())
);
}
}
您可以详细了解here。
您也可以在上面的LoaderInterceptor
中使用计数器变量。显然,这是一个主题,您将根据此值向LoaderService
发出(在根据调用启动/完成的调用递增/递减之后),其中show
变量将在计数器为{大于0,反之亦然。