fix(ivy): ng-content tags in re-inserted templates should walk declaration tree (#27783)
This PR assures that content projection works if an <ng-content> tag is placed inside an <ng-template> in one component and that <ng-template> is inserted into a different component. It fixes a bug where the projection instruction code would walk up the insertion tree to find selector data instead of the declaration tree. PR Close #27783
This commit is contained in:
@ -21,7 +21,7 @@ import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TN
|
||||
import {DECLARATION_VIEW, HOST_NODE, INJECTOR, LView, TData, TVIEW, TView} from './interfaces/view';
|
||||
import {assertNodeOfPossibleTypes} from './node_assert';
|
||||
import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state';
|
||||
import {getHostTElementNode, getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, isComponentDef, stringify} from './util';
|
||||
import {findComponentView, getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, isComponentDef, stringify} from './util';
|
||||
|
||||
|
||||
/**
|
||||
@ -320,7 +320,8 @@ export function getOrCreateInjectable<T>(
|
||||
let previousTView: TView|null = null;
|
||||
let injectorIndex = getInjectorIndex(tNode, lView);
|
||||
let parentLocation: RelativeInjectorLocation = NO_PARENT_INJECTOR;
|
||||
let hostTElementNode: TNode|null = flags & InjectFlags.Host ? getHostTElementNode(lView) : null;
|
||||
let hostTElementNode: TNode|null =
|
||||
flags & InjectFlags.Host ? findComponentView(lView)[HOST_NODE] : null;
|
||||
|
||||
// If we should skip this injector, or if there is no injector on this node, start by searching
|
||||
// the parent injector.
|
||||
|
@ -263,28 +263,16 @@ export function addAllToArray(items: any[], arr: any[]) {
|
||||
* Given a current view, finds the nearest component's host (LElement).
|
||||
*
|
||||
* @param lView LView for which we want a host element node
|
||||
* @param declarationMode indicates whether DECLARATION_VIEW or PARENT should be used to climb the
|
||||
* tree.
|
||||
* @returns The host node
|
||||
*/
|
||||
export function findComponentView(lView: LView, declarationMode?: boolean): LView {
|
||||
export function findComponentView(lView: LView): LView {
|
||||
let rootTNode = lView[HOST_NODE];
|
||||
|
||||
while (rootTNode && rootTNode.type === TNodeType.View) {
|
||||
ngDevMode && assertDefined(
|
||||
lView[declarationMode ? DECLARATION_VIEW : PARENT],
|
||||
declarationMode ? 'lView.declarationView' : 'lView.parent');
|
||||
lView = lView[declarationMode ? DECLARATION_VIEW : PARENT] !;
|
||||
ngDevMode && assertDefined(lView[DECLARATION_VIEW], 'lView[DECLARATION_VIEW]');
|
||||
lView = lView[DECLARATION_VIEW] !;
|
||||
rootTNode = lView[HOST_NODE];
|
||||
}
|
||||
|
||||
return lView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host TElementNode of the starting LView
|
||||
* @param lView the starting LView.
|
||||
*/
|
||||
export function getHostTElementNode(lView: LView): TElementNode|null {
|
||||
return findComponentView(lView, true)[HOST_NODE] as TElementNode;
|
||||
}
|
||||
|
Reference in New Issue
Block a user