即使没有进行任何更改,Angular 也无限地重新渲染是否正常?

Rau*_*ene 5 angular-template angular2-changedetection angular

问题

Angular 是否旨在不断重新检查所有内容以检测更改?我来自 React 世界,我期待像event triggered -> re-rendering. 我不知道这是来自我的应用程序还是来自 Angular。

如果我有一个从 HTML 模板调用的方法,即使我的组件中没有任何更改,它也会被无限调用。

问题

我有一个类似日历的页面,它加载了大量数据,并且必须在渲染之前进行计算,因为用ngIf指令来做这些事情太困难了。所以我的模板中有如下内容:

<div [innerHTML]="_getDayPrice(item, day) | safeHtml"></div>  
Run Code Online (Sandbox Code Playgroud)

如果我在_getDayPrice方法中控制台记录一些东西,它会被无限打印

我试过的

  1. 我已经通过ChangeDetectionRef在我的应用程序中手动注入并执行this.cdRef.detach(). 然而,这感觉很糟糕,因为有时我可能需要重新启用它并再次分离。

  2. 我试图调查它是否来自我的父组件应用程序,比如容器。我在我的主 app.component 中渲染了一个 div ,<div class={{computeClass()}}>并在该方法中打印了一个控制台日志,果然它被无限调用。因此,在此之后,我尝试注释掉所有应用程序的服务。如果全部都被注释掉了,它就可以正常工作,但也没有可观察到的数据。我已经调查了大约半天,但没有发现单点故障(比如注释掉这个服务可以解决所有问题)。

  3. 使用 chrome 的内置性能选项卡记录性能,但再次从我的代码中找不到任何触发更改的内容。zone.js被反复调用并似乎设置了一个持续发射的间隔。

  4. 当然,我已经搜索了服务中的setTimeoutsetInterval,但找不到可能导致此问题的不断变化的内容。

结论?

底线是:如果您有一个复杂的 Angular 应用程序并从模板中调用一个方法,以便无限调用该方法,这是否正常?

如果没有,您对可能导致这种情况的原因有任何提示吗?或者有什么其他方法可以绕过它而不是分离 changeRef 检测器?

我唯一关心的是性能。这是一个类似于日历的页面,可以呈现多行,并且在 8GB RAM 的笔记本电脑上严重滞后。我很确定平板电脑或手机几乎会死机。

Jus*_*uVh 9

在 HTML 中转换数据时,应尽可能多地使用管道。

管道仅在管道对象或参数更改时重新评估(因此,如果输入之一是对象,请确保创建该对象的新实例以触发重新评估)。对于大多数用途,您可以使用管道而不是函数。

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'getDayPrice'
})
export class GetDayPricePipe implements PipeTransform {

  transform(item: string, day: string): string {
    // ... do whatever logic here
    return item + day;
  }

}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

<div [innerHTML]="item | getDayPrice:day | safeHtml"></div>
Run Code Online (Sandbox Code Playgroud)

  • 有关管道的更多信息,我建议观看 5 分钟的 youtube 视频:“提高性能 - 不仅仅是一个白日梦”,作者是 Tanner Edwards 在 ng-Conf 中 (2认同)