我有一个带有角度2的测试应用程序构建,我已成功在路由更改之间应用了一个动画
state('default',style({ opacity: 1,transform: 'scale(1) translateY(0)' })),transition('void <=> default',[ style({ opacity: 0,transform: 'scale(.9) translateY(-20px)' }),animate('.2s') ])
但是当列表页面更改为项目页面时,我也想要一个不同的动画,比如单击英雄列表中的英雄,所以我这样做了
state('childActivate',transition('childActivate => void',[ animate('1.2s',style({ transform: 'scale(0.9) translateY(-120px)',opacity: 0 })) ])
我在点击某个项目之后和导航之前尝试将状态设置为’childActivated’:
onHeroSelected(heroEvent: Hero) { this.animState = "childActivate"; this.router.navigate(['/hero-detail',heroEvent.id]); }
但没有效果.
如何在路线之间获得多个动画?
将状态设置为“childActivate”无效,因为组件在下一个更改检测步骤中被销毁,因此状态切换为void.
这就是我解决这个问题的方法:
我将路线更改延迟了1个更改检测周期.我为此使用CanDeactivate Guard,它侦听要解析的承诺.
看看我的plnkr:
https://embed.plnkr.co/cOeDfXCetaYuXFaZ7WeO/
在路由定义中我添加:
canDeactivate: [CanDeactivateAfterChangeDetectionGuard]
这是CanDeactivate Guard:
@Injectable() class CanDeactivateAfterChangeDetectionGuard implements CanDeactivate<WaitForChangeDetection> { canDeactivate(component: WaitForChangeDetection): Promise<boolean> { return component.waitForChangeDetection(); } }
适用于实现此接口的任何组件:
declare abstract class WaitForChangeDetection { abstract waitForChangeDetection(): Promise<boolean>; }
我创建了一个带有此接口的默认实现的基本组件
@Component({}) class WaitForChangeDetectionImpl implements AfterViewChecked,WaitForChangeDetection { constructor(private cdRef: ChangeDetectorRef){ this.viewChecked$= new Subject<void>(); } viewChecked$: Subject<void>; waitForChangeDetection(): Promise<boolean>{ this.cdRef.detectChanges(); return new Promise((resolve) => this.viewChecked$.subscribe(() => resolve(true))); } ngAfterViewChecked(){ this.viewChecked$.next(); } }
因此,您可以扩展此组件以提供与任何组件的防护一起使用的功能.
@Component({}) class ComponentA extends WaitForChangeDetectionImpl { ...