Angular 2 - router: How to animate page transition

2019-06-04 00:23发布

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 {}

2条回答
迷人小祖宗
2楼-- · 2019-06-04 01:05

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!

查看更多
Fickle 薄情
3楼-- · 2019-06-04 01:05

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

查看更多
登录 后发表回答