我尝试了this解决方案,但似乎对我不起作用。
我所做的是(或多或少)将this example中的代码实现到我的客户端。但是,我来自另一条路线。我想从/login
导航到/home
。
/login
本身确实有一些动画:
login.animation.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();
}
问题是动画根本没有被执行。
答案 0 :(得分:0)
如果您希望在继续导航之前完成组件中的所有动画,则应实施CanDeactivate
后卫。向所有动画完成后发出的组件添加observable(您可以收听所有动画的.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();
}
}
<强>登录-routing.module.ts 强>
const routes: Routes = [
{
path: 'login',
component: LoginComponent,
canDeactivate: [LoginCanDeactivateGuard],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [LoginCanDeactivateGuard],
})
export class LoginRoutingModule {}