函数被调用多次

function gets called several times

我想显示一个dataList。有些值是从函数计算得出的。 angular2 似乎多次调用计算函数。

  <tr *ngFor="let data of dataList">
    <td>{{ data.no }}</td>
    <td>{{ data.name }}</td>
    <td>{{ calculateFunction(data.price) }}</td>
  </tr>

控制台会输出"calculate..."多次,超过dataList.length.

calculateFunction() {
  console.log('calculate...');
  return ...;
}

我应该担心性能问题还是让 angular2 这样做?

每次 Angular 运行 组件的更改检测(更准确地说是 ngFor 创建的嵌入视图)都会调用 caculateFunction(data.price) 函数。这是因为更新 DOM 是变更检测的一部分,而 Angular 需要调用 caculateFunction 来了解要用于 DOM 更新的值。而且变化检测周期可以 运行 相当频繁。因此,如果您在列表中有 3 个项目并且 CD 最初被触发了 3 次,您将看到该函数被调用了 9 次。

如果您检查 updateRenderer 函数,您应该会看到以下内容:

function(_ck,_v) {
    var _co = _v.component;
    var currVal_0 = _co.calculateFunction(_v.context.$implicit);
    _ck(_v,3,0,currVal_0);
  }

详细了解 Angular 如何在 The mechanics of DOM updates in Angular 中更新 DOM。

Should I worry about that for performance or just let angular2 do this?

如果 calculateFunction(data.price) returns 以相同的价格获得相同的结果,最好事先为每个项目计算这些值,然后简单地在模板中渲染它们。

<td>{{ data.no }}</td>
<td>{{ data.name }}</td>
<td>{{ data.calculatePrice) }}</t

通过这种方式,您将避免性能下降的函数调用。

您可以将组件 changeDetectionStrategy 更改为 onPush。之后,您的 calculateFunction 函数不会调用多次。

这样做 :

在您的组件中:

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css'],
 changeDetection: ChangeDetectionStrategy.OnPush // this line
})

export class AppComponent {

  ....

  calculateFunction(value) {
    console.log('calculate...');
    return ...;
  }
}

在你的 app.component.html 中:

 <tr *ngFor="let data of dataList">
  <td>{{ data.no }}</td>
  <td>{{ data.name }}</td>
  <td>{{ calculateFunction(data.price) }}</td>
 </tr>

已更新

处理这种情况的最佳方法是使用 Pipe,如下所示:

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

@Pipe({
  name: 'handlePrice'
})
export class HandlePricePipe implements PipeTransform {
  transform(price: number): number {
    console.log('In Pipe ....');
    return price * 2;
  }
}

然后使用那个:

<tr *ngFor="let data of dataList">
   <td>{{ data.no }}</td>
   <td>{{ data.name }}</td>
   <td>{{ data.price |handlePrice }}</td>
</tr>
@Component({
.
.
 changeDetection: ChangeDetectionStrategy.OnPush // this line
})
export class MyComponent {
}

为组件装饰器添加变更检测解决了我的问题。