我试图在Angular中设置一些路线变化的动画。动画应该在任何内容和内容的高度之间设置高度动画。当内容提前知道时,这非常有效,请参阅此plunkr:http://plnkr.co/edit/FOZSZOJaSpLbrs2vl6Ka
然而,当http请求发生时,它确实不能很好地工作。请参阅此plunkr:http://plnkr.co/edit/vyobBtb5KDO7nkYLLsto(这里使用延迟的rx操作模拟了http请求)
如果动画在内容加载之前没有开始,我会完全没问题,但我怀疑这是可能的。
我认为是错误的,是Angular正在测量" twoComponent"当它被插入时,但在它完成加载之前,然后导致这一点。
总体上没有正确使用代码:
//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {RouterModule, Routes} from '@angular/router';
import {HashLocationStrategy} from '@angular/common';
import {animate, animateChild, query, style, transition, trigger} from '@angular/animations';
import {Observable} from 'rxjs/Observable';
import {of} from 'rxjs/observable/of';
import 'rxjs/add/operator/delay';
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<a routerLink="">Go to one</a>
<a routerLink="two">Go to two</a>
<div [@routeAnimations]="prepareRoute(outlet)"
style="background-color:pink"
id="main-router-outlet">
<router-outlet #outlet="outlet"></router-outlet>
</div>
</div>
`,
animations: [
trigger('routeAnimations', [
transition('* => *', [
query(':enter', [
style({height: 0, opacity: 0, width: 0}),
], {optional: true}),
query(':leave', [
style({height: '*', width: '*'}),
animate('200ms', style({opacity: 0})),
animate('500ms', style({height: 0, width: 0})),
], {optional: true}),
query(':enter', [
animate('500ms', style({height: '*', width: '*'})),
animate('500ms', style({opacity: 1})),
animateChild(),
], {optional: true}),
]),
]),
],
styles: [
`#main-router-outlet ::ng-deep > * {
display: block;
} `
]
})
export class App {
name:string;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
public prepareRoute(outlet: RouterOutlet) {
return outlet.activatedRouteData['animation'] || '';
}
}
@Component({
template: `one component<br>more`
})
export class oneComponent {
}
@Component({
template: `two component
<div *ngFor="let s of dynamicContent|async">
{{s}}
</div>
`
})
export class twoComponent {
public dynamicContent: Observable<string[]>;
ngOnInit() {
this.dynamicContent = of(['foo', 'bar', 'baz'])
.delay(200);
}
}
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot([{
path: '',
component: oneComponent,
data: {
animation: 'one',
}
},
{
path: 'two',
component: twoComponent,
data: {
animation: 'two',
}
}], { useClass: HashLocationStrategy })
],
declarations: [ App, oneComponent, twoComponent ],
bootstrap: [ App ]
})
export class AppModule {}
答案 0 :(得分:3)
使用解析器: Demo
<强>解析器强>
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot,ActivatedRoute } from '@angular/router';
import { ContactsService } from './contacts.service';
@Injectable()
export class ArrResolve implements Resolve<string[]> {
constructor() {}
resolve(route: ActivatedRouteSnapshot) {
return of(['foo', 'bar', 'baz'])
.delay(200);
}
}
<强>的AppModule 强>
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot([{
path: '',
component: oneComponent,
data: {
animation: 'one',
}
},
{
path: 'two',
component: twoComponent,
data: {
animation: 'two',
},
resolve: {
arr: ArrResolve
}
}], { useClass: HashLocationStrategy })
],
declarations: [ App, oneComponent, twoComponent ],
bootstrap: [ App ],
providers: [ArrResolve]
})
export class AppModule {}
两个组件
@Component({
template: `two component
<div *ngFor="let s of dynamicContent|async">
{{s}}
</div>
`
})
export class twoComponent {
public dynamicContent: Observable<string[]>;
constructor(private route:ActivatedRoute) {
}
ngOnInit() {
this.dynamicContent = of(this.route.snapshot.data.arr);
}
}