我有一个带加载栏的组件,它可以显示和隐藏一个名为isLoading
的布尔变量。例如:
ngOnInit() {
this.isLoading = true;
this.someService.getAll().subscribe(data => {
// some code...
this.isLoading = false;
});
}
<loading-bar *ngIf="isLoading"></loading-bar>
但我有一个问题,当主组件中有子组件,并从它们加载数据时。加载栏应该位于主组件中,并且仅当来自所有子组件的数据到达时才应隐藏。实现这一目标的最佳方法是什么?
发布于 2019-06-21 03:25:15
您可以使用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>
当然,您必须在模块的提供者数组中注册HTTPListener和HTTPStatus服务。
谢谢。
发布于 2019-06-21 02:26:59
您可以为每个子组件设置isLoaded标志。然后,通过服务将标志状态共享给您的父组件。父组件的isLoaded标志将是子组件的isLoaded的组合
发布于 2019-06-21 03:10:21
我们放在整个应用程序上的加载器不就是这种情况吗?
您需要“实现”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
(根据调用initiated/completed递增/递减之后),其中当计数器大于0时,show
变量将变为true
,反之亦然。
https://stackoverflow.com/questions/56691849
复制相似问题