簡體   English   中英

如何使Angular動畫等待渲染完成

[英]How to make Angular animations wait for rendering to finish

我正在嘗試為Angular中的某些路線變化設置動畫。 動畫的高度應在沒有內容和內容的高度之間設置動畫。 如果提前知道該內容,則效果很好,請參見以下代碼: http ://plnkr.co/edit/FOZSZOJaSpLbrs2vl6Ka

但是,當必須發出http請求時,它不能很好地工作。 請參閱以下代碼: http ://plnkr.co/edit/vyobBtb5KDO7nkYLLsto(此處使用延遲rx操作模擬了http請求)

我會完全滿意動畫,直到內容加載完畢才開始,但是我懷疑這是可能的。

我認為出了問題,是Angular在“ twoComponent”插入時但在完成加載之前正在測量“ 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 {}

使用解析器: 演示

分解器

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);
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM