我正在尝试设置一个路由器动画,当用户点击任何[routerLink]时,它会向一个方向滑动,但是当用户触发history.back()时,单击页面内的按钮或点击它们浏览器后退按钮,我希望动画朝相反的方向发展。
这是我到目前为止的解决方案。
主要组件Html
<div class="inicio" [@routerTransition]="getState(o)" (@routerTransition.start)="animationStarted($event)" (@routerTransition.done)="animationDone($event)">
<router-outlet #o="outlet"></router-outlet>
</div>
主要组件TS
getState(outlet: RouterOutlet) {
let state: number = this.appRouterState.getState(outlet.activatedRouteData.state);
return state;
}
当用户前进或状态时 - 当用户后退时
,这是返回状态++动画触发器设置
return trigger('routerTransition', [
transition('void => *', [
query(':enter, :leave', style({ position: 'fixed', width: '100%', height: "100%" }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))], { optional: true }),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))], { optional: true })
])
]),
transition(':increment', [
query(':enter, :leave', style({ position: 'fixed', width: '100%', height: "100%" }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))], { optional: true }),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))], { optional: true })
])
]),
transition(':decrement', [
query(':enter, :leave', style({ position: 'fixed', width: '100%', height: "100%" }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))], { optional: true }),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' }))], { optional: true })
])
])
]);
州控制服务
export interface ItemHistorico {
index: number;
url: string;
}
@Injectable()
export class AppRouterState {
private lastIndex: number = 0;
private isBack: boolean = false;
private historico: ItemHistorico[] = [];
constructor(private router: Router, private menuService: MenuService) { }
public loadRouting(): void {
this.router.events.filter(event => event instanceof NavigationEnd).subscribe(({ urlAfterRedirects }: NavigationEnd) => {
if (urlAfterRedirects !== "/") {
let last: ItemHistorico = _.maxBy(this.historico, h => h.index);
let max: number = last ? last.index : 1;
let next = max + 1;
this.historico = [...this.historico, { index: next, url: urlAfterRedirects }];
if (!this.isBack) {
this.lastIndex++;
}
else {
this.isBack = false;
}
}
else {
this.menuService.obterPaginaInicial().subscribe(menuItem => {
let url = menuItem.url;
this.router.navigate([`/${url}`]);
});
}
});
window.onpopstate = ev => {
let hash: string = (ev.currentTarget as Window).location.hash;
if (hash === "#/") {
this.isBack = false;
}
else {
this.isBack = true;
this.lastIndex--;
}
};
}
public getHistory(): ItemHistorico[] {
return this.historico;
}
public getState(current: string): number {
return this.lastIndex;
}
public getIsBack(): boolean {
return this.isBack;
}
}
Obs。:“void =&gt; *”转换正在运行,“:increment”也正常工作,问题出在用户倒退时,虽然状态发生变化且组件加载没有问题动画不会触发器。
请求帮助。
答案 0 :(得分:0)
我设法解决了这个问题。所以对于那些需要类似解决方案的人来说:
主要组件模板
<div class="inicio" [@routerTransition]="getState(o)">
<router-outlet #o="outlet"></router-outlet>
</div>
主要组件类
currentState: number = 0;
lastPage: string;
getState(outlet: RouterOutlet) {
let state: string = outlet.activatedRouteData.state;
if (this.lastState !== state) {
let dir: string = this.appRouterState.getDirection(state);
if (dir === "f") {
this.currentState++;
}
else {
this.currentState--;
}
this.lastPage= state;
}
return this.currentState;
}
历史导航控制服务
@Injectable()
export class AppRouterState {
private history: string[] = [];
private isBack: boolean;
constructor(private router: Router) { }
public loadRouting(): void {
this.router.events.filter(event => event instanceof NavigationEnd).subscribe(({ urlAfterRedirects }: NavigationEnd) => {
this.history= [...this.history, urlAfterRedirects ];
});
window.onpopstate = ev => {
this.isBack = true;
};
}
public getHistory(): string[] {
return this.history;
}
public getDirection(page: string): string {
if (this.isBack) {
if (`/${page}` === this.history[this.history.length - 3]) {
this.history.splice(this.history.length - 2, 2);
this.isBack = false;
return "b";
}
}
return "f";
}
}
动画设置
export function routerTransition() {
return trigger('routerTransition', [
transition(':increment', [
query(':enter, :leave', style({ position: 'fixed', width: '100%', height: "100%" }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))], { optional: true }),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' }))], { optional: true })
])
]),
transition(':decrement', [
query(':enter, :leave', style({ position: 'fixed', width: '100%', height: "100%" }), { optional: true }),
group([
query(':enter', [style({ transform: 'translateX(-100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))], { optional: true }),
query(':leave', [style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))], { optional: true })
])
])
]);
}
答案 1 :(得分:0)
仅对那些到达这里的人有所提示。该解决方案自2019年5月起生效。只需进行一些更正和提醒。
除此之外,只要您使用了正确的语法并将动画添加到路由器出口包装div中,那么您就可以开始使用了!