如何等待动画结束再导航到下一个路线?



>我已经尝试过这个解决方案,但它似乎对我不起作用。

我所做的是(或多或少)将此示例中的代码实现到我的客户端中。但是,我来自另一条路线。我想从/login导航到/home

/login本身确实有一些动画:

登录.动画.ts

import {
sequence, trigger, stagger, animate, style, group, query as q, transition, keyframes, animateChild,
state
} from '@angular/animations';
const query = (s,a,o={optional:true})=>q(s,a,o);
export const listAnimation = trigger('listAnimation', [
transition(':enter, :leave', [
query('.container', style({opacity: 0}), {optional: true}),
query('.container', stagger('300ms', [
animate('1s ease-in', keyframes([
style({opacity: 0, transform: 'translateY(-75%)', offset: 0}),
style({opacity: .5, transform: 'translateY(35px)', offset: 0.3}),
style({opacity: 1, transform: 'translateY(0)', offset: 1.0})
]))]), {optional: true})    
])
]);

login.component.ts

import {Component, OnInit} from '@angular/core';
import {FormBuilder, Validators} from '@angular/forms';
import {HttpClient} from '@angular/common/http';
import {AuthenticationService} from '../../service/authentication.service';
import {Router} from '@angular/router';
import {NGXLogger} from 'ngx-logger';
import {listAnimation} from './login.animation';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
animations: [
listAnimation
],
host: {
'[@listAnimation]': ''
}
})
export class LoginComponent implements OnInit {
public loginForm = this.formBuilder.group({
username: [null, Validators.required],
email: [],
password: [null, Validators.required],
passwordConfirm: [null, Validators.required]
});
constructor(private formBuilder: FormBuilder, private http: HttpClient,
private router: Router, private logger: NGXLogger,
private authenticationService: AuthenticationService) { }
ngOnInit(): void {
if (AuthenticationService.isLoggedIn()) {
this.logger.debug('Already logged in. Goto /home.');
this.router.navigate(['/home']);
}
}
onSubmit(): void {   
this.onLoginSuccess();
}
onCancel(): void {
this.router.navigate(['/']);
}
private onLoginSuccess(): void {
this.router.navigate(['/home']);
}
}

在这里,我希望/home等到/login完成。

router.animation.ts中,我有您在第一个示例中看到的动画以及第二个示例中的建议transition('route1 => route2', animations)

import {
sequence, trigger, stagger, animate, style, group, query as q, transition, keyframes, animateChild,
state
} from '@angular/animations';
import {listAnimation} from './component/login/login.animation';
const query = (s,a,o={optional:true})=>q(s,a,o);
export const routerTransition = trigger('routerTransition', [
transition('* => *', [
query(':leave', animateChild()),          
query(':enter', animateChild())
]),
transition('login => home', listAnimation)
]);

一切都有效,除了/home不等待的事实。当/login执行其动画时,/home直接弹出并弄乱了场景。

显然我错过了一些东西 - 我必须添加什么才能使这项工作?


使用CanDeactivate

扩展login.component.html以便我可以侦听动画事件:

<form [formGroup]="loginForm" (ngSubmit)="onSubmit()" [@listAnimation]="3"
(@listAnimation.start)="animationStart($event)"
(@listAnimation.done)="animationDone($event)">

以及在login.component中.cs

animationStart() {
console.log('START');
}
animationDone() {
console.log('END');
}
canDeactivate(): Observable<boolean> {
console.log('login.component.ts canDeactivate()');
return this.animationsDoneSource.asObservable();
}

问题是动画根本没有执行。

如果您希望在继续导航之前完成组件中的所有动画,则应实现CanDeactivate保护。将可观察添加到所有动画完成后发出的组件(您可以侦听所有动画.done事件),并在CanActivate守卫中使用它。

login.component.ts

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
animations: [
listAnimation
],
host: {
'[@listAnimation]': ''
}
})
export class LoginComponent implements OnInit {
private animationsDoneSource = new Subject<boolean>();
@HostListener('@listAnimation.done') onDone() {
this.animationsDoneSource.next();
this.animationsDoneSuorce.complete();
}
canDeactivate(): Observable<boolean> {
return this.animationsDoneSource.asObservable();
}
}

login.guard.ts

@Injectable()
export class LoginCanDeactivateGuard implements CanDeactivate<LoginComponent> {
canDeactivate: Observable<boolean>(
component: LoginComponent,
): Observable<boolean> {
return component.canDeactivate();
}
}

login-routing.module.ts

const routes: Routes = [
{
path: 'login',
component: LoginComponent,
canDeactivate: [LoginCanDeactivateGuard],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [LoginCanDeactivateGuard],
})
export class LoginRoutingModule {}

最新更新