在学习 overlay 和 portal 的时候,一直没有弄明白 viewContainerRef 在其中扮演的角色
这里说一下来龙去脉
当我们创建一个 overlay 时,同时创建了一个 portal outlet
当我们要 append 内容时,内部其实时调用了 DomPortalOutlet 的 attachComponentPortal 方法
这时候会依据 portal <-- 传入的component portal,不是 portal outlet 哦,不要搞混了.
时候有 viewContainerRef 决定如何创建 component.
如果有就调用 viewContainerRef create component 方法, 这时会 insert component to container 渲染. 然后再通过 dom 操作 cut and paste 去 portal outlet (body)。
如果没有的话就直接通过 component factory create component 然后把 view 放入到全局 appRef 里面. 这时候组件并没有 append to dom 任何地方.
然后 cut and paste to portal outlet.
当 app.tick 时,所有的 appRef.views 就会 detech change.
2 者有什么区别呢 ?
在 portal 的文档里并没有解释太多... 只是说什么逻辑树和 view 树的不同而已.
反而是 dialog 的文档里解释了
从源码上看确实如此.
在使用了 viewContainerRef 之后, detech change 的时机是依据 viewContainerRef 的
而放入 appRef 的情况, detech change 的时机是 app.tick 每一次都触发.
appRef.attachView 将 view 放入了一个 array 中.
在 tick 的时候调用 detech change.
至于 injector 其实蛮困惑的,因为 attachComponentPortal injector 是基于 component portal 的 injector,跟 viewContainerRef 没有啥关系丫. 那为什么 dialog 文档说有关系呢
看了源码就会发现了,dialog 创建 portal 使用的 injector 是 userInjector || rootInjector, 而所谓的 userInjector 就是 viewContainerRef.injector.
这样就真相大白了咯。