2017-04-18 2 views
2

Ich versuche, eine einfache Komponente zu erstellen, die ein boolesches Flag isLoading hat, das true ist, wenn eine Route mehr als eine halbe Sekunde zur Auflösung benötigt hat.Winkel 4: Route Übergang Laden

Ich habe das Stück, um sie auszuschalten:

this.router.events 
     .filter(event => event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) 
     .subscribe(event => this.isLoading = false); 

Aber wie sage ich:

this.router.events 
     //given a NavigationStart 
     //If you don't see NavigationEnd/NavigationCancel/NavigationError within 500ms 
     .subscribe(event => this.isLoading = true); 

Antwort

0

Jeder Satz von Routing-Ereignisse ID haben. Wenn die ID geändert wurde, musst du den Spinner umschalten.

3

Ich habe gerade dies, ohne spezielle Timer:

constructor(private authService: AuthService, 
      private messageService: MessageService, 
      private router: Router) { 

    router.events.subscribe((routerEvent: Event) => { 
     this.checkRouterEvent(routerEvent); 
    }); 
} 

checkRouterEvent(routerEvent: Event): void { 
    if (routerEvent instanceof NavigationStart) { 
     this.loading = true; 
    } 

    if (routerEvent instanceof NavigationEnd || 
     routerEvent instanceof NavigationCancel || 
     routerEvent instanceof NavigationError) { 
     this.loading = false; 
    } 
} 

Und es funktioniert gut. Wenn die Route schnell geladen wird, wird kein Drehfeld angezeigt. Wenn der Routen-Resolver etwas Zeit in Anspruch nimmt, wird der Drehfeld angezeigt.

Dieser Code ist von der „Angular Routing“ Plural Kurs hier: https://app.pluralsight.com/library/courses/angular-routing

+0

Dank Deborah beginnen - Ich denke, dass diese Lösung vom Computer/Browser des Benutzers abhängig ist, was sie letztendlich sehen. Ich möchte mehr Kontrolle über es mit einer bestimmten Entprellzeit haben, wenn möglich – John

+0

die 500ms Timeout wird nicht auf diese Weise behandelt werden. Der beste Weg ist die Verwendung von rxjs .debounce (500) als @KeniSteward, wie unten vorgeschlagen. Sie können einen Rückruf haben, um das Timeout manuell zu behandeln, aber RxJs stellt bereits die Funktion bereit, um es zu behandeln. –

1

denke ich jetzt bin ich mit dieser Lösung gehen gehen:

ngOnInit() { 
    let timer: any; 

    this.router.events 
     .subscribe(event => { 
      if (event instanceof NavigationStart) { 
       clearTimeout(timer); 
       timer = setTimeout(() => this.isLoading = true, 250); 
      } else if (event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) { 
       clearTimeout(timer); 
       this.isLoading = false; 
      } 
     }); 
} 

Wenn jemand eine sauberere RxJs Weg postet zu gehen darüber werde ich beachten sie, dass

bearbeiten: Basierend auf @ KeniSteward Antwort zu arbeiten, ich war in der Lage, diese Lösung zu erhalten:

this.router.events 
     .filter(event => event instanceof NavigationStart || event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) 
     .debounceTime(250) 
     .filter(event => event instanceof NavigationStart) 
     .subscribe(event => this.isLoading = true); 

    this.router.events 
     .filter(event => event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) 
     .subscribe(event => this.isLoading = false); 

bearbeiten # 2: Noch sauberer -

this.router.events 
     .filter(event => event instanceof NavigationStart || event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) 
     .do(event => this.isLoading = false) 
     .debounceTime(250) 
     .filter(event => event instanceof NavigationStart) 
     .subscribe(event => this.isLoading = true); 
1
let isLoading: boolean = false; 

ngOnInit() { 
    this.router.events.subscribe((event) => { 
     if (event instanceof NavigationStart) { 
      this.isLoading = true; 
     } 
     if (event instanceof NavigationEnd) { 
      this.isLoading = false; 
     } 
    }); 
} 
3
this.router.events 
     .debounceTime(500) 
     .filter(event => event instanceof NavigationStart) 
     .subscribe(event => this.isLoading = true); 

Was dies sagt, ist:

.debounceTime(500) = wenn ein anderes Ereignis erstellt wird, bevor 500 ms mich

unterdrücken

.filter(event => event instanceof NavigationStart) = nur nehmen NavigateStart von den Ereignissen, die nicht befolgt werden mit 500ms

.subscribe(event => this.isLoading = true); = wir wissen jetzt, dass es ein Navigations Start war, die nicht innerhalb von 500 ms gefolgt wurde, so dass wir das Laden Symbol

+0

Ich denke, das muss debounceTime gegen Entprellen sein. Ich habe es gerade ausprobiert und es funktionierte nicht für mich: das Problem ist mehrere 'RouteConfigLoadStart' und' RouteConfigLoadEnd' wird während dieser Ladeperiode auftreten, die die Debounce-Zählung zurücksetzt. – John

+0

Meine Entschuldigung, ich dachte, die einzigen Ereignisse waren NavigationStart/End/Abbrechen/Fehler. Aktualisierung auf debounceTime. Ist es möglich, dass du einen Daumen nach oben geben kannst, damit ich genügend Kommentare bekomme, um Kommentare zu schreiben? Haha – KeniSteward