首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在所有子组件和子组件中的数据到达Angular之前,显示加载栏的最佳方式是什么

在所有子组件和子组件中的数据到达Angular之前,显示加载栏的最佳方式是什么
EN

Stack Overflow用户
提问于 2019-06-21 02:21:57
回答 3查看 1K关注 0票数 2

我有一个带加载栏的组件,它可以显示和隐藏一个名为isLoading的布尔变量。例如:

代码语言:javascript
复制
ngOnInit() {
  this.isLoading = true;
  this.someService.getAll().subscribe(data => { 
    // some code...
    this.isLoading = false;
  });
}
代码语言:javascript
复制
<loading-bar *ngIf="isLoading"></loading-bar>

但我有一个问题,当主组件中有子组件,并从它们加载数据时。加载栏应该位于主组件中,并且仅当来自所有子组件的数据到达时才应隐藏。实现这一目标的最佳方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-06-21 03:25:15

您可以使用HttpInterceptor来感知应用程序中正在进行的任何HTTP活动,并创建一个在其中保留HTTP活动标志的服务。现在,在根组件中,只需检查该标志并显示一个正在加载的微调器。这样,您就不必单独处理每个子组件和子组件的加载栏的显示。

HTTPInterceptor及相关服务的代码如下。

代码语言:javascript
复制
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服务。

代码语言:javascript
复制
  HTTPActivity: boolean;

  constructor(private httpStatus: HTTPStatus) {
    this.httpStatus.getHttpStatus().subscribe(status => { this.HTTPActivity = status; });
  }

在组件的.html部分,现在可以通过检查HTTPActivity布尔变量来显示/隐藏加载栏或微调器。

代码语言:javascript
复制
<div id="preloader" [hidden]=!HTTPActivity>
  <div id="loader"></div>
</div>

当然,您必须在模块的提供者数组中注册HTTPListener和HTTPStatus服务。

谢谢。

票数 5
EN

Stack Overflow用户

发布于 2019-06-21 02:26:59

您可以为每个子组件设置isLoaded标志。然后,通过服务将标志状态共享给您的父组件。父组件的isLoaded标志将是子组件的isLoaded的组合

票数 1
EN

Stack Overflow用户

发布于 2019-06-21 03:10:21

我们放在整个应用程序上的加载器不就是这种情况吗?

您需要“实现”HttpInterceptor,并通过将它们与加载器服务相关联来使用其中的加载器。

下面是HttpInterceptor的一个示例实现。

代码语言:javascript
复制
@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,反之亦然。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56691849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档