Это потому, что вы нарушаете цикл обнаружения изменений Angular.
Вот что происходит после того, как вы нажмете первую кнопку-переключатель:
1- Вы нажимаете на переключатель
2- ZoneJS, у которого есть хуки в событиях кликов, получает уведомление (проще говоря)
3- Zone гарантирует, что событие щелчка завершено
4- Zone сообщит Angular, что произошло событие async
, мы должны проверить компонент и убедиться, что представление (DOM) отражает модель (модель / мир javascript). Итак, change detection
запустится, обнаружит все изменения и обнаружит, что в шаблоне есть привязки (ng-if
).
5- После того, как ngIf
станет истинным, И ЗАМЕТЬТЕ, ЧТО ЭТО ВСЕ СИНХРОНИЗАЦИЯ ТАК ДАЛЕКО, создается ng-container
, создается ваш templateOutlet
, а ваш hello
компонент будет визуализирован.
ОБРАТИТЕ ВНИМАНИЕ: все это синхронизируется.
6 - Просмотр был обновлен, обнаружение изменений отключено.
7 - Внутри вашего hello
компонента вы запускаете другое событие, которое является created
и которое уведомляет родительский компонент, а внутри вашего родительского компонента вы изменяете массив, и Angular не заботится об этом, потому что там hasn ' Это было асинхронным событием, и вы не обновляли какие-либо входные данные, вы только что запустили другое событие синхронизации после того, как обнаружение изменений завершило свою работу.
8- Массив теперь обновлен, а представление - нет (в родительском компоненте)
9 - Вы нажимаете еще раз, происходит то же самое, и Angular обновляет родительское представление при первом запуске обнаружения изменений, и вы видите, что массив отражается в представлении.
Чтобы доказать свою правоту: D:
onTemplateCreated() {
console.log('Got the event from chil');
this.template.push('Template created');
console.log('this.template',this.template);
}
Вы увидите, что после щелчка на консоли отображается правильный массив, но вид не отображается, пока вы не нажмете еще раз.
Теперь перейдем к моему коду
onTemplateCreated() {
console.log('Got the event from chil');
this.template = [...this.template,'Template created'];
}
BE потому что я не мутирую, и ссылка обновляется, Angular теперь должен позаботиться об этом изменении, НО проблема все еще существует, детектор изменений Angular завершен, и вы обновили модель без запуска какого-либо события async
, так что у нас проблемы, потому что Angular не хочет, чтобы модель обновлялась после завершения обнаружения изменений,
Таким образом, вы получите сообщение об ошибке:
ExpressionChangedAfterItHasBeenCheckedError: выражение изменилось после проверки. Предыдущее значение
Чтобы исправить это, сначала прочтите мой другой пост, чтобы понять его , во-вторых, вам нужно сообщить Angular, что вы знаете, что делаете, и запустить обнаружение изменений вручную:
this._cd.detectChanges
ИЛИ вы можете сделать это асинхронным:
onTemplateCreated() {
console.log('Got the event from chil');
setTimeout(()=>{
this.template = [...this.template,'Template created'];
})
}
person
Milad
schedule
09.04.2018