以以下(简化的)代码为例:
/* 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
数组时,浏览器就会冻结,因此所有动画都会冻结。
在更新和渲染过程中,有什么办法可以让动画运行?
答案 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)以显示微调框。