web-dev-qa-db-de.com

Aktivitätsanzeige anzeigen, während ein faul geladenes Modul in Angular 2 geladen wird

Mein Szenario sieht wie folgt aus. Ich habe ein Menü mit mehreren Optionen. Jedes Menü sollte abhängig von den Benutzerberechtigungen angezeigt werden (bereits gelöst), die meisten Menüelemente sind als Module gekapselt und die meisten Module sind faul geladen. Wenn also ein Benutzer das erste Mal auf ein Menüelement klickt, wird dieses geladen (bis hierher alles) funktioniert gut), jetzt ist meine Anforderung, um eine bessere Benutzererfahrung zu erzielen, muss ich Aktivitätsanzeige anzeigen, nachdem der Benutzer einen Menüpunkt anklickt, während das faul geladene Modul geladen wird.

Bislang habe ich es mit canActive, canLoad, canActivateChild-Schnittstellen vom Angular Router versucht, aber ohne Erfolg. 

Irgendwelche Ideen?

15
vicmac

Sie können auf zwei Router-Ereignisse warten:

  • RouteConfigLoadStart
  • RouteConfigLoadEnd

Sie werden ausgelöst, wenn ein faul geladenes Modul geladen wird. Der Vorteil dieser Verwendung gegenüber den Standardrouterereignissen wie NavigationStart ist, dass sie nicht bei jeder Routenänderung ausgelöst werden.

Hören Sie sie in Ihrer root AppComponent an, um Ihren Spinner anzuzeigen/auszublenden.

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

Nur eine einfache Zeichenfolge hier, aber Sie könnten eine Spinner-Komponente verwenden.

<router-outlet></router-outlet>

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

Ich verwende diesen Ansatz mit Angular v4.2.3

35
Daniel Crisp

sie können es so machen 

  1. in app.component.html
<div class="main-loader" *ngIf="loading">
  <div class="cssload-container" >
      <div class="cssload-whirlpool"></div>
  </div>
</div>
  1. in app.component.ts

    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. in css jede ladende Animation 

hoffe das ist nützlich für dich. Vielen Dank

19

Sie können einfach CSS verwenden!

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

In deiner Vorlage

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

.loader {
  opacity : 0;
}

Dann können Sie ausgefallene Spinner mit HTML/CSS erstellen

0
YounesM

für diejenigen, die Kompatibilität mit IE11 benötigen (und damit umgehen), funktioniert die akzeptierte Antwort nicht, da IE11 den Loader nicht rendert, wenn von einem Modul zu einem anderen gewechselt wird. Daher habe ich eine (nicht sehr elegante, aber funktionierende) Problemumgehung durchgeführt:

Klicken Sie in meinem menuItem-Schalter auf Ereignis:

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

Es ist möglich, beim Laden der ersten Route auf einen Link zu einer anderen faul geladenen Route zu klicken. Deshalb müssen wir die geladenen Routen zählen:

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>

0
Azargoth