在 Angular 2 中加载延迟加载模块时显示活动指示器



我的场景如下。我有一个菜单,有多个选项。每个菜单都应该根据用户权限(已经解决(显示,大多数菜单项被封装为模块,并且大多数模块都是延迟加载的,所以当用户第一次单击菜单项时,它会加载(到目前为止一切正常(,现在我的要求是,为了提供更好的用户体验, 我需要在用户在加载延迟加载模块时单击菜单项后显示活动指示器。

到目前为止,我尝试使用来自Angular Router的canActive,canLoad,canActivateChild接口,但没有运气。

有什么想法吗?

您可以侦听两个路由器事件:

  • RouteConfigLoadStart
  • RouteConfigLoadEnd

它们在加载延迟加载的模块时触发。与标准路由器事件(如 NavigationStart(相比,使用这些事件的优势在于它们不会在每次路由更改时触发。

在您的根应用程序组件中收听它们以显示/隐藏您的微调器。

app.component.ts

import { Router, RouteConfigLoadStart, RouteConfigLoadEnd } from '@angular/router';
...
export class AppComponent implements OnInit {
    loadingRouteConfig: boolean;
    constructor (private router: Router) {}
    ngOnInit () {
        this.router.events.subscribe(event => {
            if (event instanceof RouteConfigLoadStart) {
                this.loadingRouteConfig = true;
            } else if (event instanceof RouteConfigLoadEnd) {
                this.loadingRouteConfig = false;
            }
        });
    }
}

app.component.html

这里只是一个简单的字符串,但您可以使用微调器组件。

<router-outlet></router-outlet>
<ng-container *ngIf="loadingRouteConfig">Loading route config...</ng-container>

我在 Angular v4.2.3 中使用这种方法

你可以这样做

  1. 在应用程序组件中.html
<div class="main-loader" *ngIf="loading">
  <div class="cssload-container" >
      <div class="cssload-whirlpool"></div>
  </div>
</div>
  1. 在应用程序中。

    import { Router, NavigationStart, NavigationEnd } from '@angular/router';
    
    loading:boolean = false;
    constructor(private router:Router) { 
      router.events.subscribe(event => {
        if(event instanceof NavigationStart) {
          this.loading = true;
          console.log("event started")
        }else if(event instanceof NavigationEnd) {
          this.loading = false;
          console.log("event end")
        }
        // NavigationEnd
        // NavigationCancel
        // NavigationError
        // RoutesRecognized
      });
    }
    
  2. 在 CSS 中任何加载动画

希望这对你有用。

谢谢

你可以使用 CSS !

<routler-outlet></routler-outlet>
<div class='.loader>
  Just, wait a sec ! I'm loading
</div>

在您的模板中

router-outlet + .loader {
  opacity : 1;
}
.loader {
  opacity : 0;
}

然后你可以用HTML/CSS创建花哨的微调器

可以在加载第一个路由时单击指向其他延迟加载路由的链接。这就是为什么我们需要计算正在加载的路由:

app.component.ts

'

''

export class AppComponent { 
  currentlyLoadingCount = this._router.events.scan((c, e) => this._countLoads(c, e), 0);
  constructor(private _router: Router) { }
  private _countLoads(counter: number, event: any): number {
    if (event instanceof RouteConfigLoadStart) return counter + 1;
    if (event instanceof RouteConfigLoadEnd) return counter - 1;
    return counter;
  }
'

''

app.component.html <ng-container *ngIf="currentlyLoadingCount | async">Loading route config...</ng-container>

对于那些

需要与IE11兼容(和处理(的人来说,接受的答案不起作用,因为IE11在从一个模块切换到另一个模块时不会呈现加载器,所以我做了一个(不是很优雅但可以工作(解决方法:

在我的菜单中,项目切换单击事件:

  public navigate(url: string) {
    this.configurationService.loading = true; //service variable linked with html loader
    //let's give time to tortoise IE11 to render loader before navigation...
    let obj = this;
    setTimeout(function() 
    {
      obj.router.navigateByUrl(url);
    }, 1);
  }

最新更新