Author: Miško Hevery
LView
where the <ng-template>
was declared. In our case it would be the LView
of AppComp
.LView
where the instance of <ng-template>
has been inserted. In our example it would be the LView
of LibComp
.LView
: Transplant LView
is the LView
where the insertion point LView[PARENT]
and declaration LView[DECLARATION_VIEW]
do not match. In our example this would be LView
created by the LibComp
from the TemplateRef
which was declared at AppComp
.AppComp
) and the library author (LibComp
) are two different developers, therefore the assumptions of one should not leak into the other. For example the LibComp
should be free to decide if the LibComp
is OnPush
or Always
without effecting the kinds of assumptions AppComp
has. To put it differently LibComp
should be able to change from Always
to OnPush
without breaking CD for the transplanted LView
.
LView
. (Author of the template controls the CD strategy.)AppComp |
LibComp |
Outcome |
---|---|---|
Always |
Always |
Run CD through all LView s on each tick. |
Always |
OnPush |
Changing AppComp.name should trigger the update of the binding {{greeting}} {{name}}! regardless if LibComp is dirty. |
OnPush |
Always |
Changing LibComp.greeting should trigger the update of the {{greeting}} {{name}}! regardless if the AppComp is dirty. |
OnPush |
OnPush |
Changing LibComp.greeting or AppComp.name should trigger the CD of the template. |
What the above table suggest is that the transplantedLView
should be CDed if either the AppComp.name
or the LibComp.greeting
changes. In other words the transplant LView
is subject to being marked dirty by either the AppComp
or LibComp
being marked dirty.
NOTE:
LView
is detached it should not be CDed. (This behavior is different from VE)Suppose both AppComp
and LibComp
are OnPush
. Which views should be CDed when either AppComp
or LibComp
change state and are marked dirty?
AppComp .name |
LibComp .greeting |
Transplanted {{greeting}} {{name}}! |
AppComp: {{name}}! |
LibComp: {{greeting}}! |
Outcome |
---|---|---|---|---|---|
- | - | - | - | - | when neither component is marked dirty a CD run should not update any of the bindings. |
mutate | - | Update | Update | - | When AppComp is marked dirty than {{greeting}} {{name}}! , AppComp: {{name}}! should be updated, but LibComp: {{greeting}}! should not be updated. |
- | mutate | Update | - | Update | When LibComp is marked dirty than {{greeting}} {{name}}! , LibComp: {{greeting}}! should be updated, but AppComp: {{name}}! should not be updated. |
mutate | mutate | Update | Update | Update | When LibComp and AppComp is marked dirty than {{greeting}} {{name}}! , LibComp: {{greeting}}! , and AppComp: {{name}}! should be updated. |
The implications from the above table are that:
AppComp
being marked dirty should CD its transplanted LView
but it should not cause CD in LibComp
.
LibComp
as well.LibComp
being marked dirty should CD its transplanted LView
but it should not cause CD in AppComp
.
LView
should not be CD in either case.
LView
is detached.The implication from the above discussion is that the <ng-template>
needs to keep track of the transplanted LView
instances so that it can invoke change detection on them from both declared as well as inserted view.
LView
currently keeps track of all components in LView[CHILD_HEAD|CHILD_TAIL|NEXT]
(in addition to LView
). This is unnecessary because we already keep track of all child components in TView.components
. Removing them would speed up creation and updates as tracking and iterating requires time.LView
s should be added the the declared LView
linked-list.
LView[PARENT] !== LView[DECLARATION_VIEW
(transplanted) and LView[PARENT] !== null
(attached).LView[PREV]
to make it efficient to remove transplanted LView
s. This is an additional cost to the LView
as it will increase its header size by one slot.LibComp
we should always visit any (including transplanted) view at insertion point (current behavior).LView
we should also visit the transplanted views in the LView[CHILD_HEAD|CHILD_TAIL|NEXT]
.
LView
we will run the CD on the transplanted LView
twice. Once from the AppComp
and once from the LibComp
. We could guard against this, but that would require additional work and checks, and given that this scenario is rare, I don't think it is worth worrying about this double checking.LibComp
and than have the LibCom
be detached. In such a situation one would expect that the template does not get CD under any use case, but in our case it would get CDed in the case when the AppCom
would get marked as dirty.