条件:在 Angular 中输入组件动画
Conditional :enter Animation of Component in Angular
鉴于我的应用路线:
const appRoutes: Routes = [
{
path: '', component: HomeComponent, children: [
{path: 'datascreen', component: DataComponent},
{path: '', component: IntroComponent}
]
}
];
我有一个默认情况下应该显示 IntroComponent 的主屏幕。当用户单击该 Intro-component 上的按钮时,它会导航到 DataComponent。
通过 DataComponent 上的按钮,用户可以导航回 Intro-Component。
HomeComponent 的模板只包含插座:
<router-outlet></router-outlet>
我确实想向 IntroComponent 添加 slide-in/slide-out 动画。这可以通过在“:enter”和“:leave”上使用触发器向 IntroComponent 添加动画来轻松完成。这很好用。
但是现在第一次渲染屏幕时也会显示这个动画。这看起来有点令人困惑。
所以我的问题是:
如何向仅在初始加载后执行的 IntroComponent 添加动画?或者换句话说:如何在组件第二次出现时执行 :enter 动画?
创建 angular 动画时,您有一些重要的状态。第一个状态是void => *
。这与 shorthand :enter
相同
当您第一次加载视图时,您正在点击该动画事件。
如果你在组件中放置一个触发器,那么每次你启动该组件时它都会触发该触发器,就像每次你 运行 一个组件它都会触发 ngOnInit 中的代码一样。因此,您的问题的解决方案是将动画移出组件,而不是使用控制整个应用程序动画的动画触发器包裹路由器插座。
您想将 :enter
设置为您的应用程序加载的任何动画,例如淡入淡出或相关的东西,然后您会想要使用您的设置从路线 1 到路线 2 的动画滑入和滑出方法。这样,如果您导航它会左右滑动,但如果您加载它就会淡入。
取自YearofMoo
Year of Moo Routable Animations
app.html
<div [@routeAnimation]="prepRouteState(routerOutlet)">
<!-- make sure to keep the ="outlet" part -->
<router-outlet #routerOutlet="outlet"></div>
<div>
然后
app.ts
@Component({
animations: [
trigger('routeAnimation', [
// no need to animate anything on load
transition(':enter', []),
// when we go away from the home page to support
transition('homePage => supportPage', [
group([
query(':enter', [
style({ opacity: 0 }),
animate('0.5s', style({ opacity: 1 }))
]),
query(':leave', [
animate('0.5s', style({ opacity: 0 }))
])
])
]),
// and when we go back home
transition('supportPage => homePage', [
// ...
])
])
]
})
class AppComponent {
prepRouteState(outlet: any) {
return outlet.activatedRouteData['animation'] || 'firstPage';
}
}
app.ts
const ROUTES = [
{ path: '',
component: HomePageComponent,
data: {
animation: 'homePage'
}
},
{ path: 'support',
component: SupportPageComponent,
data: {
animation: 'supportPage'
}
}
]
鉴于我的应用路线:
const appRoutes: Routes = [
{
path: '', component: HomeComponent, children: [
{path: 'datascreen', component: DataComponent},
{path: '', component: IntroComponent}
]
}
];
我有一个默认情况下应该显示 IntroComponent 的主屏幕。当用户单击该 Intro-component 上的按钮时,它会导航到 DataComponent。
通过 DataComponent 上的按钮,用户可以导航回 Intro-Component。
HomeComponent 的模板只包含插座:
<router-outlet></router-outlet>
我确实想向 IntroComponent 添加 slide-in/slide-out 动画。这可以通过在“:enter”和“:leave”上使用触发器向 IntroComponent 添加动画来轻松完成。这很好用。
但是现在第一次渲染屏幕时也会显示这个动画。这看起来有点令人困惑。
所以我的问题是: 如何向仅在初始加载后执行的 IntroComponent 添加动画?或者换句话说:如何在组件第二次出现时执行 :enter 动画?
创建 angular 动画时,您有一些重要的状态。第一个状态是void => *
。这与 shorthand :enter
当您第一次加载视图时,您正在点击该动画事件。 如果你在组件中放置一个触发器,那么每次你启动该组件时它都会触发该触发器,就像每次你 运行 一个组件它都会触发 ngOnInit 中的代码一样。因此,您的问题的解决方案是将动画移出组件,而不是使用控制整个应用程序动画的动画触发器包裹路由器插座。
您想将 :enter
设置为您的应用程序加载的任何动画,例如淡入淡出或相关的东西,然后您会想要使用您的设置从路线 1 到路线 2 的动画滑入和滑出方法。这样,如果您导航它会左右滑动,但如果您加载它就会淡入。
取自YearofMoo Year of Moo Routable Animations
app.html
<div [@routeAnimation]="prepRouteState(routerOutlet)">
<!-- make sure to keep the ="outlet" part -->
<router-outlet #routerOutlet="outlet"></div>
<div>
然后
app.ts
@Component({
animations: [
trigger('routeAnimation', [
// no need to animate anything on load
transition(':enter', []),
// when we go away from the home page to support
transition('homePage => supportPage', [
group([
query(':enter', [
style({ opacity: 0 }),
animate('0.5s', style({ opacity: 1 }))
]),
query(':leave', [
animate('0.5s', style({ opacity: 0 }))
])
])
]),
// and when we go back home
transition('supportPage => homePage', [
// ...
])
])
]
})
class AppComponent {
prepRouteState(outlet: any) {
return outlet.activatedRouteData['animation'] || 'firstPage';
}
}
app.ts
const ROUTES = [
{ path: '',
component: HomePageComponent,
data: {
animation: 'homePage'
}
},
{ path: 'support',
component: SupportPageComponent,
data: {
animation: 'supportPage'
}
}
]