2017-12-16 14 views
1

일부 경로 변경 사항을 애니메이션으로 애니메이션하려고합니다. 애니메이션은 높이와 내용 높이 사이에서 움직여야합니다. 콘텐츠가 미리 알려지면 잘 작동합니다. 자세한 내용은 다음을 참조하십시오. http://plnkr.co/edit/FOZSZOJaSpLbrs2vl6Ka각도 애니메이션을 렌더링 대기 완료

http 요청을해야하는 순간에는 제대로 작동하지 않습니다. 이 plunkr을보십시오 : http://plnkr.co/edit/vyobBtb5KDO7nkYLLsto (여기서 http 요청은 지연된 rx 연산을 사용하여 시뮬레이트되었습니다)

내용이로드 될 때까지 애니메이션이 시작되지 않는 것이 좋겠지 만 그럴 가능성은 있습니다.

내가 잘못 추측 한 것은 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 {} 
+2

구성 요소 : https://angular.io/api/router/Resolve –

답변

1

사용 리졸버 : 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); 
    } 
}