为什么模板在角度4中被编译四次?

时间:2017-11-17 11:51:49

标签: angular angular2-changedetection

我从一个角度模板(插值)内部调用一个函数,奇怪的是该函数被调用了四次!!

我确实知道变化检测如何在角度中起作用,因为我知道如果绑定值得到更新,变化检测过程就会启动。

在这种情况下,我没有约束/改变任何东西......

var i = 0;

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>{{ parentCounter() }}</h1>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    
  }
  
  parentCounter(){
    alert(`${++i} called`);
    return 5;
  }
}

参考:https://plnkr.co/edit/pta0s0nzcsLdTsjCtb3D?p=preview

注意:模板在异步事件之前编译了四次

Template got compiled four times before the async event

2 个答案:

答案 0 :(得分:1)

enter image description here

enter image description here

如前面的答案评论中所述,每次都有两个电话,因为您可以在图片中看到,由于后续呼叫(幂等测试),检查值未发生变化。第一组2个调用是从页面的引导/初始解析启动的,第二对调用是由于readystatechange事件触发而触发,自动区域/异步处理程序触发视图更新。

另外,添加这个实际上是微不足道的。性能问题来自于具有通常在转发器中的组件的页面,其具有大量数据绑定,导致具有数万个数据绑定的页面(然后人们抱怨它很慢:))检查时间轴和铬分析工具它们是非常宝贵的,另外,为了深入研究这个问题,我使用debugger关键字和调用堆栈来查看一般情况。

答案 1 :(得分:0)

如果绑定到视图中的函数,如

<h1>{{ parentCounter() }}</h1>

然后每次运行更改检测时,Angular都会调用此函数。

如果此函数每次调用时都返回一个新对象,您甚至会在开发模式下获得异常。

  

表达式自上次检查后发生了变化

最好将调用结果分配给字段并改为绑定到该字段。

var i = 0;

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>{{ counter }}</h1>
    </div>
  `,
})
export class App {
  name:string;
  counter:number;
  constructor() {
    this.counter = this.parentCounter();
  }

  parentCounter(){
    alert(`${++i} called`);
    return 5;
  }
}