Почему шаблон компилируется четыре раза в angular 4?

Я вызываю функцию из углового шаблона (интерполяция), как ни странно, функция вызывается четыре раза !!

Я знаю, как работает обнаружение изменений в angular, поскольку я понял, что процесс обнаружения изменений запускается, если значение привязки обновляется.

В этом сценарии я ничего не привязываю/не меняю как таковой.

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

Примечание. Шаблон был скомпилирован четыре раза до асинхронного события.

Шаблон был скомпилирован четыре раза до асинхронного события


person kalki    schedule 17.11.2017    source источник
comment
stackoverflow.com/questions/45412199/   -  person yurzui    schedule 19.11.2017
comment
stackoverflow.com/questions/ 41187667/   -  person yurzui    schedule 19.11.2017


Ответы (2)


Если вы привязываетесь к функциям в представлении, например

<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;
  }
}
person Günter Zöchbauer    schedule 17.11.2017
comment
Я знаю об этом. Но я хочу знать, почему обнаружение изменений происходит четыре раза? - person kalki; 17.11.2017
comment
В режиме разработки Angular запускает обнаружение изменений дважды каждый раз, чтобы проверить наличие ошибки, упомянутой в моем ответе (выражение изменилось...). Поэтому Angular запускает обнаружение изменений дважды при запуске вашего приложения. Я не знаю точно, почему. После этого он запускается один раз (двойной дубль), когда происходит событие. См. журнал консоли stackblitz.com/edit/angular-gn8gga. - person Günter Zöchbauer; 17.11.2017
comment
И когда Гюнтер говорит о событиях, он имеет в виду каждое событие браузера. Каждое записываемое движение мыши или нажатие на клавиатуру и т. д. запускает обнаружение изменений. - person jcairney; 02.10.2019
comment
Только события, к которым привязан компонент Angular или его потомок. Я не видел, чтобы другие события вызывали запуск обнаружения изменений. - person Günter Zöchbauer; 03.10.2019

введите здесь описание изображения

введите здесь описание изображения

Как указано в предыдущих комментариях к ответу, каждый раз выполняется два вызова, как вы можете видеть на рисунках, чтобы проверить, не изменилось ли значение из-за последующих вызовов (идемпотентный тест). Первый набор из двух вызовов инициируется начальной загрузкой/начальным синтаксическим анализом страницы, вторая пара вызовов запускается в результате срабатывания события readystatechange и автоматического обработчика зоны/асинхронного запуска обновления представления.


Кроме того, просто добавить это действительно будет незначительным. Проблемы с производительностью возникают из-за страниц, которые обычно содержат компоненты в повторителях с тоннами привязок данных, ведущих к страницам с десятками тысяч привязок данных (а затем люди жалуются, что это медленно :)). Проверьте временную шкалу и инструменты профилирования Chrome, они бесценны, также, чтобы копаться в этом самостоятельно, я использовал ключевое слово debugger и стек вызовов, чтобы увидеть, что происходит в целом.

person shaunhusain    schedule 17.11.2017
comment
Спасибо за ответ !! Я только что попробовал еще раз, сохранив точки отладчика, и обнаружил, что этот шаблон оценивается четыре раза (часть обнаружения изменений) перед событием readyStateChange из зоны js.. Загрузил изображение, касающееся этого, пожалуйста, проверьте его.. Поправьте меня, если я ошибаюсь . - person kalki; 19.11.2017