hannes neukermans
hannes neukermans

Reputation: 13257

Angular 2 - router: How to animate page transition during route resolve

Currently inside my NG2 app I'm using a resolver, that makes a connection to signalr.
I have configured the resolver inside my route config, so when navigation to the destination page, the resolve function is called accordingly.

I've managed to show an animation when the destination page is initialized.

However, I would like to show an 'is-busy' like animation DURING the resolving of my resolver, but I don't know how to do this. Any suggestions?

This is my current setup:

//resolver.ts
@Injectable()
export class ConnectionResolver implements Resolve<SignalRConnectionMock> {

constructor(private _signalR: SignalR) {}

   resolve() {
      console.log('HomeRouteResolver. Resolving...');
      return new SignalRConnectionMock();// this._signalR.connect();
   }
}

//inside route.ts
{ path: 'docs', 
  component: DocumentationComponent, 
  resolve: { connection: ConnectionResolver }
}

//router.ts
import { trigger, state, animate, style, transition } from '@angular/core';

//router.transition.ts
export function routerTransition() {
   return slideToLeft();
}

function slideToLeft() {
  return trigger('routerTransition', [
    state('void', style({position: 'fixed', width: '100%'}) ),
    state('*', style({position: 'fixed', width: '100%'}) ),
    transition(':enter', [  // before 2.1: transition('void => *', [
      style({transform: 'translateX(100%)'}),
      animate('0.5s ease-in-out', style({transform: 'translateX(0%)'}))
    ]),
    transition(':leave', [  // before 2.1: transition('* => void', [
      style({transform: 'translateX(0%)'}),
       animate('0.5s ease-in-out', style({transform: 'translateX(-100%)'}))
    ])
 ]);
}

//home.component.ts
import { routerTransition } from './route.transition';

@Component({
   selector: 'home',        
   animations: [routerTransition()],
   host: {'[@routerTransition]': ''}
})
export class HomeComponent {}

Upvotes: 1

Views: 4564

Answers (2)

YairTawil
YairTawil

Reputation: 4101

You can catch the router events! you have for example: NavigationStart NavigationEnd.

when you navigate, NavigationStart will send first, then its call the "resolve" promise and when the resolve finished. NavigationEnd will send with and your "leave" animation will start.

first you should inject "Router" inside component constructor:

import {Router} from "@angular/router";
 constructor(private router:Router){}

next you should call events Observable, you should filter events, make sure you navigate outside of 'home' state and take make sure it's happen only once :

  import {NavigationEnd, NavigationStart} from "@angular/router";
  import 'rxjs/add/operator/take';
  import 'rxjs/add/operator/filter';

   constructor(private router:Router){
     router.events.filter(e => e instanceof NavigationStart && !router.isActive("home", false) ).take(1).subscribe(() => { 
         // resolve has been call here! "is-busy"        
      }

     router.events.filter(e => e instanceof NavigationEnd && !router.isActive("home", false)).take(1).subscribe(() => { 
        // resolve finished here!  end of "is-busy" start of "leave" animation  

      }
   }

Good Luck!

Upvotes: 1

hjl
hjl

Reputation: 2802

You can have a loading component in your root app component, and then listen on navigation event. Build a navigation intercepor make loading component active when navigation starts and deactive when navigation ends.

Take a look at this solution, it's probably what you want: Show loading screen when navigating between routes in Angular 2

Upvotes: 2

Related Questions