web-dev-qa-db-fra.com

Afficher l'indicateur d'activité lors du chargement d'un module chargé paresseux dans Angular 2

Mon scénario est le suivant. J'ai un menu avec plusieurs options. Chaque menu doit être affiché en fonction des autorisations de l'utilisateur (déjà résolu), la plupart des éléments de menu sont encapsulés en tant que modules et la plupart des modules sont chargés paresseux. Ainsi, lorsqu'un utilisateur clique sur un élément de menu pour la première fois, il se charge (jusqu'à présent, tout fonctionne bien), maintenant, mon exigence est la suivante: afin de donner une meilleure expérience utilisateur, je dois afficher un indicateur d’activité lorsque l’utilisateur clique sur un élément de menu pendant le chargement du module chargé paresseux.

Jusque-là, j'ai essayé d'utiliser les interfaces canActive, canLoad, canActivateChild de Angular Router mais sans succès. 

Des idées?

15
vicmac

Vous pouvez écouter deux événements de routeur:

  • RouteConfigLoadStart
  • RouteConfigLoadEnd

Ils se déclenchent lorsqu'un module chargé paresseux est en cours de chargement. L'avantage d'utiliser ces événements par rapport aux événements de routeur standard tels que NavigationStart est qu'ils ne se déclencheront pas à chaque changement d'itinéraire.

Écoutez-les dans votre racine AppComponent pour afficher/masquer votre disque.

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

Juste une simple chaîne ici, mais vous pouvez utiliser un composant spinner.

<router-outlet></router-outlet>

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

J'utilise cette approche avec Angular v4.2.3

35
Daniel Crisp

tu peux le faire comme ça 

  1. dans app.component.html
<div class="main-loader" *ngIf="loading">
  <div class="cssload-container" >
      <div class="cssload-whirlpool"></div>
  </div>
</div>
  1. dans 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. en css toute animation de chargement 

espérons que cela vous sera utile. Merci

19

Vous pouvez simplement utiliser CSS!

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

Dans votre template

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

.loader {
  opacity : 0;
}

Ensuite, vous pouvez créer fantaisie spinners avec HTML/CSS

0
YounesM

pour ceux qui ont besoin de compatibilité (et de transaction) avec IE11, la réponse acceptée ne fonctionne pas, car IE11 ne rend pas le chargeur lors du passage d'un module à un autre.

Dans mon événement de clic menuItem switch:

  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

Il est possible de cliquer sur un lien vers un autre itinéraire chargé paresseux lors du chargement du premier. C'est pourquoi nous devons compter les itinéraires en cours de chargement:

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