繁体   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