我一直在使用 ng-template 并发现自己在为某种延迟而苦苦挣扎。
我在 stackblitz 中创建了一个简单的示例。 https://stackblitz.com/edit/angular-template-series-v?file=app%2Fparent%2Fparent1.component.ts
Parent 组件通过模板发送一个Hello 组件给它的Child。
我们的想法是从 child 使用ngIf。
当 Hello 组件到达 ngOnInit Hook 周期时,它会发出输出。父组件获取此输出并添加要显示的消息。
但是在创建组件时而不是在一个周期之后显示该消息。在该示例中,您需要单击两次“切换内容”按钮才能显示“已创建模板”消息。
如何解决这个问题才能使消息出现在同一个周期中?
最佳答案
这是由于 Angular 中更改检测的工作方式所致。它没有链接到使用 ng-template
,因为这 modified stackblitz显示(使用孙子而不使用 ng-template)。
关于变化检测需要知道的两件事:
- 它在事件(点击、提交等)、xhr 请求或计时器之后触发。
- 它在组件树中从上到下出现
基本上,当您单击切换按钮时:
- 处理程序被触发(在您的示例中切换
showContent
的值,但没有别的。hello
组件不是在此创建阶段) - 变化检测开始,总是从上到下开始。
- angular 首先检查是否需要为父组件更新 View 。由于尚未发生任何变化,因此不会更新父 View 。
- 然后子组件检测到它的
showContentValue
已经改变。这会导致创建hello
组件。 hello
组件初始化后,created
事件被触发。父组件收到此事件并相应地更新消息数组。但是此时父 View 的内容已经被检查过了,所以 Angular 不会对父 View 做任何修改。
当你再次点击切换按钮时,同样的循环再次运行,这次显示的是上一个循环中推送到数组中的消息
这是一个modified stackblitz example带有生命周期钩子(Hook)的日志
注意
强制更改检测再次运行将解决您的问题,但如果您不是直接从子级到父级进行通信,您最好使用共享服务(基于可观察对象)在不相关的组件之间广播消息
关于Angular 模板通信延迟一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49532860/