使用延迟加载的路由/模块在启动时加载Angular 5 Spinner

时间:2018-03-14 16:38:18

标签: angular spinner lazy-loading angular-router angular-module

在Angular 5中,如果请求的路线/模块延迟加载,如何在应用启动上显示loading spinner

我的第一个想法是简单地将微调器代码包含在<app-root>标记内(请参阅this question,特别是Christophe Vidal对已接受答案的评论)。

这很好,然而,如果在应用启动时出现问题,请求的路由恰好是与延迟加载的路由/模块相对应的路由。

在这种情况下,微调器最初将按预期显示,但会过早消失。更具体地说,当微调器消失时,在实际内容出现之前还有明显的时间。

我认为这个延迟是由于延迟加载导致<app-root>中的微调器已被覆盖,即使没有内容吗?

的index.html

<app-root>
    <div class="loading">
        <!-- loading spinner here -->
    </div>
</app-root>

在这种情况下,您将如何展示加载微调器?

注意:我不是在通过http获取数据时询问是否显示微调器,我要求在启动应用程序时显示微调器。

2 个答案:

答案 0 :(得分:2)

我对此的看法是在初始化时订阅应用根app.component.ts中的Angular路由器事件。但是,重要的是要注意,这不仅会导致在加载延迟加载的组件时显示微调器,而且还会导致在导航到任何路径时显示。 (这可能不是你想要的)

ngOnInit(){
 router.events.subscribe( (event: Event) => {

            if (event instanceof NavigationStart) {
                /*Display your spinner*/
            }

            if (event instanceof NavigationEnd) {
                /*Hide your spinner*/
            }
        });
}

***更新***

我发现你可以绑定到<router-outlet>,这将允许你确定正在加载的组件。我知道斗争是让旋转器只在加载延迟加载的组件后才停止旋转。通过绑定到router-outlet中的app.component.ts,您可以确定正在加载的组件,并在此时停止微调器。

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'my-app',
  template: `<router-outlet #outlet></router-outlet>`
})
export class AppComponent implements AfterViewInit {
  @ViewChild(RouterOutlet)
  public outlet: RouterOutlet;

  public ngAfterViewInit(): void {
    this.outlet.activateEvents.subscribe((component) => {
      if (component.__proto__.constructor.name === 'myLazyComponent') {
        //Hide Spinner
      }
    });
  }
}

答案 1 :(得分:1)

有路由器events:RouteConfigLoadStart和RouteConfigLoadEnd,因此代码为:

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'my-app',
  template: `<app-spinner *ngIf="showSpinner"></app-spinner><router-outlet></router-outlet>`
})
export class AppComponent implements AfterViewInit {
  showSpinner: boolean = false;

  constructor(private router: Router) {
      this.router.events.subscribe(
              event => {
                if(event instanceof RouteConfigLoadStart) {
                  showSpinner = true;
                  return;
                }
                if(event instanceof RouteConfigLoadEnd) {
                  showSpinner = false;
                  return;
                }
          }
      );
   }
}

app-spinner组件可以是浏览器窗口中间带有某种旋转图标的叠加层。