UPDATE: 3 Now that I have upgraded to the new router, the @borislemke approach will not work if you use the CanDeactivate guard. I am humbled by my old method, ie: this answer
UPDATE2 : the router events in the new router look promising, and the @borislemke answer below (now above) seems to cover the main aspect of spinner implementation, I havenβt tested it, but I recommend it.
UPDATE1: I wrote this answer in the Old-Router era when there was only one route-changed event notified via router.subscribe() . I also felt the overload of the approach below and tried to do this using only router.subscribe() , and backfired , because canceled navigation could not be detected. So I had to go back to a lengthy approach (double work).
If you know your way in Angular2, this is what you need
Boot.ts
import {bootstrap} from '@angular/platform-browser-dynamic'; import {MyApp} from 'path/to/MyApp-Component'; import { SpinnerService} from 'path/to/spinner-service'; bootstrap(MyApp, [SpinnerService]);
Root component (MyApp)
import { Component } from '@angular/core'; import { SpinnerComponent} from 'path/to/spinner-component'; @Component({ selector: 'my-app', directives: [SpinnerComponent], template: ` <spinner-component></spinner-component> <router-outlet></router-outlet> ` }) export class MyApp { }
Spinner-Component (subscribe to Spinner-service to change the value of active accordingly)
import {Component} from '@angular/core'; import { SpinnerService} from 'path/to/spinner-service'; @Component({ selector: 'spinner-component', 'template': '<div *ngIf="active" class="spinner loading"></div>' }) export class SpinnerComponent { public active: boolean; public constructor(spinner: SpinnerService) { spinner.status.subscribe((status: boolean) => { this.active = status; }); } }
Spinner-Service (download this service)
Define the observable that will be signed by the spinner component to change the status when changing, and the function to know and set the counter active / inactive.
import {Injectable} from '@angular/core'; import {Subject} from 'rxjs/Subject'; import 'rxjs/add/operator/share'; @Injectable() export class SpinnerService { public status: Subject<boolean> = new Subject(); private _active: boolean = false; public get active(): boolean { return this._active; } public set active(v: boolean) { this._active = v; this.status.next(v); } public start(): void { this.active = true; } public stop(): void { this.active = false; } }
All other route components
(sample):
import { Component} from '@angular/core'; import { SpinnerService} from 'path/to/spinner-service'; @Component({ template: `<div *ngIf="!spinner.active" id="container">Nothing is Loading Now</div>` }) export class SampleComponent { constructor(public spinner: SpinnerService){} ngOnInit(){ this.spinner.stop();