在所有组件上显示加载微调器图标

时间:2018-11-14 05:46:58

标签: javascript angular typescript

我已经编写了代码,以在触发任何事件时显示所有组件上的加载微调器。它在单个组件上运行良好,但存在问题,当触发某些事件时,我必须在多个组件上显示相同的加载微调器。参见下面的代码:

  agent:
    image: portainer/agent
    environment:
      AGENT_CLUSTER_ADDR: tasks.agent
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

  portainer:
    image: portainer/portainer
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    ports:
      - target: 9000
        published: 9000
        protocol: tcp
        mode: ingress
    volumes:
      - portainer_data:/data
    networks:
      - agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]

在ngOnInit()上,我如下调用了这两个方法,然后它可以正常工作。

  tasks() {
  this.handler.activateLoader();
  this.tasksService.get(this.page, this.pageSize).subscribe(results => {
    this.handler.hideLoader();
    if (this.handler.handle(results)) {
      return;
    }
    this.tasksRes = results['data'];
    for (let i = 0; i < this.tasksRes.length; i++) {
      if (this.tasksRes[i].status == 'In_progress' && this.tasksRes[i].eventType == 'Sync' &&
        this.tasksRes[i].entityId == this.id) {
        this.progressFlag = true;
        break;
      } else {
        this.progressFlag = false;
      }
    }
    this.length = results['totalElements'];
  }, error => {
    this.handler.hideLoader();
    this.handler.error(error);
  });
}

connect() {
  let source = new EventSource('/api/v1/events/register');
  source.addEventListener('message', message => {
    this.tasks();
  });
}

实际要求是,当我运行特定事件时,该按钮将被禁用,同时将出现微调器加载。我已经实现了这一目标。但是如何在多个组件上显示相同的微调器,以便用户可以知道任务正在运行。

这就是我显示加载微调器的方式。见下文:

ngOnInit() {
  this.tasks();
  this.connect();
}

在我的代码中,我有17-17岁左右的许多组件,需要显示加载微调器。如果要全局显示微调器,则意味着可以在整个模板通用的页眉和页脚组件中显示它。谁能提供任何想法。

谢谢。

2 个答案:

答案 0 :(得分:0)

请搜索关键字HttpInterceptor了解详细信息。下面是一个简单的示例:

// siteHttpInterceptor.ts
import { Injectable } from '@angular/core';
import { HttpRequest, HttpInterceptor, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { throwError } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { LoadingService } from './loading.service';

@Injectable()
export class SiteHttpInterceptor implements HttpInterceptor {
  constructor(private loadingService: LoadingService){}
  intercept(request: HttpRequest<any>, httpHandler: HttpHandler): Observable<any> {
      /* Start loading here */
      this.loadingService.startLoading();
      return httpHandler.handle(request).pipe(
          tap((event: HttpEvent<any>) => {
              /* End loading */
              this.loadingService.endLoading();
          },
          (err: any) => {
              /* End loading */
              this.loadingService.endLoading();
          }),
          catchError(err => {
              return throwError(err);
          })
      );
  }
}

//loading.service.ts LoadingService base on Ionic framework, you can instead it
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';

@Injectable({
  providedIn: 'root'
})
export class LoadingService {

  private loaders = [];
  //sometimes, the request so quickly then close event earlier than open loading bar
  private badLoaders = 0;

  constructor(
      private loadingController: LoadingController
  ) {
  }

  async startLoading() {
      if (this.badLoaders > 0) {
          this.badLoaders --;
      } else {
          await this.loadingController.create({
              message: 'Loading ...',
          }).then(loader => {
              this.loaders.push(loader);
              loader.present().then(() => {
                  //if it is bad loader, close
                  if (this.badLoaders > 0) {
                      this.badLoaders --;
                      this.endLoading();
                  }
              });
          });
      }
  }

  endLoading() {
      let loader = this.loaders.pop();
      if (loader) {
          loader.dismiss();
      } else {
          // it is mean close event earlier
          this.badLoaders ++;
      }
  }

}

使用它,则不需要管理加载程序处理每个请求方法。

答案 1 :(得分:0)

将微调框放在主要组件上。在大多数情况下,其AppComponent是

然后将这些放在您的共享服务上

 private LoadingStatus = new Subject<boolean>();

 // Observable string streams
 IsLoading$ = this.LoadingStatus.asObservable();

 // Service message commands
 triggerLoading(status: boolean) {
   this.LoadingStatus.next(mission);
 }

然后在您的发件人组件中,从服务调用triggerLoading(true)triggerLoading(false)并在您的主要组件(AppComponent)上进行订阅:

this.shareService.IsLoading$.subscribe( data => progressFlag = data )

或以此添加您的逻辑:

this.shareService.IsLoading$.subscribe(
 data => {
   if(data) {
     // start loading logic here
   } else {
     // end loading logic here
   }
 }
)

来源:Angular - Component Interaction