【问题标题】:Angular 5 Loading Spinner on Startup with Lazy-Loaded Route/ModuleAngular 5 加载微调器在启动时使用延迟加载的路由/模块
【发布时间】:2018-08-23 07:22:48
【问题描述】:

在 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 获取数据时显示微调器,而是要在应用启动时显示微调器。

【问题讨论】:

  • 我想澄清一下您的应用程序架构。在应用启动时,从根目录路由到的第一个模块是延迟加载模块?
  • 这取决于用户请求的任何路由。但是是的,在某些情况下,路由到的第一个模块是延迟加载的模块。在这种情况下,微调器消失得太早了。我假设正在发生的事情是它在应用程序启动期间显示,但一旦控制权转移到延迟加载就消失了。因此,当延迟加载正在进行时,微调器已经消失了。
  • 所以也许我的问题的一个更好的标题是:“如何在延迟加载期间显示加载微调器”?
  • 我认为你的标题很清楚。我只是想确保您有其他可能的路线,这些路线可能会在启动期间从根目录加载。否则,如果唯一立即加载的模块是一个惰性模块,那么使用延迟加载就没有多大意义,这会破坏延迟加载的目的。
  • 查看更新的答案。我在工作时遇到了这种技术,它让我想起了你的问题。

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


【解决方案1】:

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

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

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

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

***更新***

我发现您可以绑定到&lt;router-outlet&gt;,这样您就可以确定正在加载的组件。我知道要让微调器在延迟加载的组件加载后才停止旋转。通过绑定到app.component.ts 中的router-outlet,您可以确定正在加载的组件并在此时停止微调器。

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
      }
    });
  }
}

【讨论】:

    【解决方案2】:

    有路由器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 组件可以是某种在浏览器窗口中间带有旋转图标的叠加层。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 2017-08-21
      • 2018-05-22
      相关资源
      最近更新 更多