在angular更新组件时是否可以运行动画?

时间:2019-03-04 15:37:25

标签: angular

以以下(简化的)代码为例:

/* TimeLine component */
<ul class="timeline">
    <li *ngFor="let message of messages; let i = index; trackBy: trackByFn">
        <timeLineItem [message]="message"></timeLineItem>
    </li>
</ul>

和timeLineItem:

/* TimeLineItem component */
<div> {{message.author}} </div>
再次

,此代码非常简化,以给出一个很好的示例。 现在,一旦我在timeLine组件上设置了messages的值,整个页面就会冻结,并且只有在timeLine组件创建了所有timeLineItem且浏览器已渲染它们之后,它才再次响应。使用messages数组中的条目数量,这需要几秒钟。在这段时间里,我想运行某种加载动画。但是,正如我所说,当我设置messages数组时,浏览器就会冻结,因此所有动画都会冻结。 在更新和渲染过程中,有什么办法可以让动画运行?

2 个答案:

答案 0 :(得分:0)

可以通过多种方式解决此问题。我认为最好的方法是使用虚拟滚动(只有少数组件可以同时渲染,并且不需要动画)。可能的解决方案可以在这里https://material.angular.io/cdk/scrolling/overview

另一种方法是使用CSS动画而不是JS动画。它们是在单独的线程中计算的,不会因js计算而停止

答案 1 :(得分:0)

使用类似ng-block-ui的东西。我将整个HTML包装在block元素中。我在app.component.html中做到这一点。

<block-ui>
...
</block-ui>

然后,在全局服务中,我公开一个属性IsLoading

  private _loading: BehaviorSubject<boolean>;
  set isLoading(value: boolean) {
    this._loading.next(value);
  }
  get loading() {
    return this._loading.asObservable();
  }

接下来,我在app.component.ts中订阅并显示加载微调器。

this.appSvc.loading.subscribe( isLoading => {
   if (isLoading) {
      this.blockUI.start('Loading...');
   } else {
      this.blockUI.stop();
   }
});

以下是在HTTP帖子中使用它的示例:

  this.appSvc.isLoading = true;
  this.http.post<UploadInfo>(`${environment.apiUrl}/api/BalanceUpload`, formData, { headers: {'filename': droppedFile.fileEntry.name, 'enctype': 'multipart/form-data'}, reportProgress: true})
     .subscribe(
        data => {            
           this.appSvc.isLoading = false;
           this.uploadInfo = data[0];
        },
        error => {
           this.appSvc.isLoading = false;                                     
        }
      )
   });

您可以在以下网址阅读更多信息:ng-block-ui

现在,您可以在应用程序中的任何位置设置isLoading(true | false)以显示微调框。