2017-03-23 41 views
8

Mój scenariusz wygląda następująco. Mam menu z wieloma opcjami. Każde menu powinno być wyświetlane w zależności od uprawnień użytkownika (już rozwiązanych), większość pozycji menu jest enkapsulowanych jako moduły, a większość modułów jest leniwych załadowanych, więc gdy użytkownik kliknie pierwszy raz w elemencie menu, ładuje się (do tego momentu wszystko działa dobrze), teraz moim wymaganiem jest, aby zapewnić lepsze wrażenia użytkownika, muszę pokazać wskaźnik aktywności po tym, jak użytkownik kliknie element menu i ładuje się załadowany leniwy moduł.Pokaż wskaźnik aktywności podczas ładowania załadowanego modułu w trybie kątowym 2

Do tego, próbowałem za pomocą CanActive, canLoad, interfejsy canActivateChild z Kątowymi routerem ale bez powodzenia,

pomysłów?

Odpowiedz

1

Możesz po prostu użyć CSS!

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

W szablonie

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

.loader { 
    opacity : 0; 
} 

Następnie można tworzyć fancy spinners with HTML/CSS

+0

możesz bardziej rozwinąć swoją odpowiedź. Mam na myśli, że mam moduł główny i moduł funkcji do zarządzania wszystkimi menu, a kiedy klikam w element menu, ładuje on leniwy załadowany moduł, więc podczas ładowania chciałbym pokazać wskaźnik aktywności, ale po leniwy moduł jest załadowany, ukryj wskaźnik aktywności. Nie widzę, jak to zastosować. – vicmac

+0

Zgaduję, że masz gniazdko routera, aby załadować swój komponent. Gdy komponent nie jest załadowany '' będzie puste. A to spowoduje wybranie opcji 'container: empty + .loader' i wyświetli twój program ładujący. Po załadowaniu danych. nie będzie już pusty, wtedy 'container: empty + .loader'selector nie będzie już aktywny, a twój loader powróci do' opacity' z 0 – YounesM

+0

@vicmac Edytowałem swoją odpowiedź. – YounesM

16

można to zrobić jak ten

  1. w app.component.html
<div class="main-loader" *ngIf="loading"> 
    <div class="cssload-container" > 
     <div class="cssload-whirlpool"></div> 
    </div> 
</div> 
  1. w 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. w css animacja ładowania

nadzieja ta jest przydatna . Dzięki

+0

Nie musisz subskrybować dwa razy. Podobnie jak w przypadku odpowiedzi Daniela Crispa, możesz zrobić to raz. To działa i lepiej jest raz zasubskrybować. –

13

Można słuchać na dwa wydarzenia Router:

  • RouteConfigLoadStart
  • RouteConfigLoadEnd

oni ogień, gdy leniwy załadowany moduł jest załadowany. Zaletą korzystania z nich w przypadku standardowych zdarzeń routera, takich jak NavigationStart, jest to, że nie będą uruchamiane przy każdej zmianie trasy.

Słuchaj ich w katalogu głównym AppComponent, aby pokazać/ukryć spinner.

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

tylko prosty ciąg tutaj, ale można użyć komponentu pokrętła.

Używam tego podejścia z Angular v4.2.3

0

Możliwe jest kliknięcie łącza do innej zaległej trasy podczas ładowania pierwszej. Dlatego musimy liczyć tras ładowane:

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

Nie pracowałem przez jakiś czas nad moim projektem. Właśnie rozwiązałem z usługą współdzieloną, która jest uruchamiana po uruchomieniu jakiegoś żądania http, częściowo rozwiązuje problem, ale ja próbuję go ASAP. Dzięki. – vicmac

0

dla tych, którzy potrzebują kompatybilnych Lity (i transakcja) z IE11, zaakceptowana odpowiedź nie działa, ponieważ IE11 nie renderuje programu ładującego podczas przełączania z jednego modułu do drugiego, więc zrobiłem (nie bardzo eleganckie, ale działające) obejście:

W moim menuItem switch click event:

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