Routing enables users to navigate between different routes in an application. When a user navigates from one route to another, the Angular router maps the URL path to a relevant component and displays its view. Animating this route transition can greatly enhance the user experience.

The Angular router comes with high-level animation functions that let you animate the transitions between views when a route changes. To produce an animation sequence when switching between routes, you need to define nested animation sequences. Start with the top-level component that hosts the view, and nest additional animations in the components that host the embedded views.

要启用路由转场动画，需要做如下步骤：

To enable routing transition animation, do the following:

为应用导入路由模块，并创建一个路由配置来定义可能的路由。

Import the routing module into the application and create a routing configuration that defines the possible routes.

添加路由器出口，来告诉 Angular 路由器要把激活的组件放在 DOM 中的什么位置。

Add a router outlet to tell the Angular router where to place the activated components in the DOM.

Let's illustrate a router transition animation by navigating between two routes, Home and About associated with the HomeComponent and AboutComponent views respectively. Both of these component views are children of the top-most view, hosted by AppComponent. We'll implement a router transition animation that slides in the new view to the right and slides out the old view when the user navigates between the two routes.

Note: Use the RouterModule.forRoot method in the root module, AppModule, to register top-level application routes and providers. For feature modules, call the RouterModule.forChild method to register additional routes.

下列配置定义了应用程序中可能的路由。

The following configuration defines the possible routes for the application.

import{NgModule} from '@angular/core';import{BrowserModule} from '@angular/platform-browser';import{BrowserAnimationsModule} from '@angular/platform-browser/animations';import{RouterModule} from '@angular/router';import{AppComponent} from './app.component';import{OpenCloseComponent} from './open-close.component';import{OpenClosePageComponent} from './open-close-page.component';import{OpenCloseChildComponent} from './open-close.component.4';import{ToggleAnimationsPageComponent} from './toggle-animations-page.component';import{StatusSliderComponent} from './status-slider.component';import{StatusSliderPageComponent} from './status-slider-page.component';import{HeroListPageComponent} from './hero-list-page.component';import{HeroListGroupPageComponent} from './hero-list-group-page.component';import{HeroListGroupsComponent} from './hero-list-groups.component';import{HeroListEnterLeavePageComponent} from './hero-list-enter-leave-page.component';import{HeroListEnterLeaveComponent} from './hero-list-enter-leave.component';import{HeroListAutoCalcPageComponent} from './hero-list-auto-page.component';import{HeroListAutoComponent} from './hero-list-auto.component';import{HomeComponent} from './home.component';import{AboutComponent} from './about.component';import{InsertRemoveComponent} from './insert-remove.component';@NgModule({imports:[BrowserModule,BrowserAnimationsModule,RouterModule.forRoot([{ path:'',pathMatch:'full',redirectTo:'/enter-leave'},{ path:'open-close', component:OpenClosePageComponent},{ path:'status', component:StatusSliderPageComponent},{ path:'toggle', component:ToggleAnimationsPageComponent},{ path:'heroes', component:HeroListPageComponent, data:{animation:'FilterPage'}},{ path:'hero-groups', component:HeroListGroupPageComponent},{ path:'enter-leave', component:HeroListEnterLeavePageComponent},{ path:'auto', component:HeroListAutoCalcPageComponent},{ path:'home', component:HomeComponent, data:{animation:'HomePage'}},{ path:'about', component:AboutComponent, data:{animation:'AboutPage'}},])],

The home and about paths are associated with the HomeComponent and AboutComponent views. The route configuration tells the Angular router to instantiate the HomeComponent and AboutComponent views when the navigation matches the corresponding path.

In addition to path and component, the data property of each route defines the key animation-specific configuration associated with a route. The data property value is passed into AppComponent when the route changes. You can also pass additional data in route config that is consumed within the animation. The data property value has to match the transitions defined in the routeAnimation trigger, which we'll define later.

注意：这个 data 中的属性名可以是任意的。例如，上面例子中使用的名字 animation 就是随便起的。

Note: The data property names that you use can be arbitrary. For example, the name animation used in the example above is an arbitrary choice.

After configuring the routes, tell the Angular router where to render the views when matched with a route. You can set a router outlet by inserting a <router-outlet> container inside the root AppComponent template.

AppComponent defines a method that can detect when a view changes. The method assigns an animation state value to the animation trigger (@routeAnimation) based on the route configuration data property value. Here's an example of an AppComponent method that detects when a route change happens.

Here, the prepareRoute() method takes the value of the output directive (established through #outlet="outlet") and returns a string value representing the state of the animation based on the custom data of the current active route. You can use this data to control which transition to execute for each route.

During a transition, a new view is inserted directly after the old one and both elements appear on screen at the same time. To prevent this, apply additional styling to the host view, and to the removed and inserted child views. The host view must use relative positioning, and the child views must use absolute positioning. Adding styling to the views animates the containers in place, without the DOM moving things around.

Use the query() method to find and animate elements within the current host component. The query(":enter") statement returns the view that is being inserted, and query(":leave") returns the view that is being removed.