@@ -18,10 +18,10 @@ import {executeHooks, executeInitHooks, queueInitHooks, queueLifecycleHooks} fro
1818import { ACTIVE_INDEX , LContainer , RENDER_PARENT , VIEWS } from './interfaces/container' ;
1919import { ComponentDefInternal , ComponentQuery , ComponentTemplate , DirectiveDefInternal , DirectiveDefListOrFactory , InitialStylingFlags , PipeDefListOrFactory , RenderFlags } from './interfaces/definition' ;
2020import { LInjector } from './interfaces/injector' ;
21- import { AttributeMarker , InitialInputData , InitialInputs , LContainerNode , LElementContainerNode , LElementNode , LNode , LProjectionNode , LTextNode , LViewNode , PropertyAliasValue , PropertyAliases , TAttributes , TContainerNode , TElementNode , TNode , TNodeFlags , TNodeType } from './interfaces/node' ;
21+ import { AttributeMarker , InitialInputData , InitialInputs , LContainerNode , LElementContainerNode , LElementNode , LNode , LNodeWithLocalRefs , LProjectionNode , LTextNode , LViewNode , LocalRefExtractor , PropertyAliasValue , PropertyAliases , TAttributes , TContainerNode , TElementNode , TNode , TNodeFlags , TNodeType } from './interfaces/node' ;
2222import { CssSelectorList , NG_PROJECT_AS_ATTR_NAME } from './interfaces/projection' ;
2323import { LQueries } from './interfaces/query' ;
24- import { ProceduralRenderer3 , RComment , RElement , RText , Renderer3 , RendererFactory3 , RendererStyleFlags3 , isProceduralRenderer } from './interfaces/renderer' ;
24+ import { ProceduralRenderer3 , RComment , RElement , RNode , RText , Renderer3 , RendererFactory3 , RendererStyleFlags3 , isProceduralRenderer } from './interfaces/renderer' ;
2525import { BINDING_INDEX , CLEANUP , CONTENT_QUERIES , CONTEXT , CurrentMatchesList , DECLARATION_VIEW , DIRECTIVES , FLAGS , HEADER_OFFSET , HOST_NODE , INJECTOR , LViewData , LViewFlags , NEXT , OpaqueViewState , PARENT , QUERIES , RENDERER , RootContext , SANITIZER , TAIL , TData , TVIEW , TView } from './interfaces/view' ;
2626import { assertNodeOfPossibleTypes , assertNodeType } from './node_assert' ;
2727import { appendChild , appendProjectedNode , canInsertNativeNode , createTextNode , findComponentHost , getChildLNode , getLViewChild , getNextLNode , getParentLNode , insertView , removeView } from './node_manipulation' ;
@@ -734,7 +734,7 @@ export function elementContainerStart(
734734 createLNode ( index , TNodeType . ElementContainer , native , null , attrs || null , null ) ;
735735
736736 appendChild ( getParentLNode ( node ) , native , viewData ) ;
737- createDirectivesAndLocals ( localRefs ) ;
737+ createDirectivesAndLocals ( node , localRefs ) ;
738738}
739739
740740/** Mark the end of the <ng-container>. */
@@ -784,7 +784,7 @@ export function elementStart(
784784 setUpAttributes ( native , attrs ) ;
785785 }
786786 appendChild ( getParentLNode ( node ) , native , viewData ) ;
787- createDirectivesAndLocals ( localRefs ) ;
787+ createDirectivesAndLocals ( node , localRefs ) ;
788788}
789789
790790/**
@@ -809,21 +809,27 @@ export function elementCreate(name: string, overriddenRenderer?: Renderer3): REl
809809 return native ;
810810}
811811
812+ function nativeNodeLocalRefExtractor ( lNode : LNodeWithLocalRefs ) : RNode {
813+ return lNode . native ;
814+ }
815+
812816/**
813817 * Creates directive instances and populates local refs.
814818 *
815- * @param localRefs Local refs of the current node
819+ * @param lNode LNode for which directive and locals should be created
820+ * @param localRefs Local refs of the node in question
821+ * @param localRefExtractor mapping function that extracts local ref value from LNode
816822 */
817- function createDirectivesAndLocals ( localRefs ?: string [ ] | null ) {
818- const node = previousOrParentNode ;
819-
823+ function createDirectivesAndLocals (
824+ lNode : LNodeWithLocalRefs , localRefs : string [ ] | null | undefined ,
825+ localRefExtractor : LocalRefExtractor = nativeNodeLocalRefExtractor ) {
820826 if ( firstTemplatePass ) {
821827 ngDevMode && ngDevMode . firstTemplatePass ++ ;
822- cacheMatchingDirectivesForNode ( node . tNode , tView , localRefs || null ) ;
828+ cacheMatchingDirectivesForNode ( lNode . tNode , tView , localRefs || null ) ;
823829 } else {
824830 instantiateDirectivesDirectly ( ) ;
825831 }
826- saveResolvedLocalsInData ( ) ;
832+ saveResolvedLocalsInData ( lNode , localRefExtractor ) ;
827833}
828834
829835/**
@@ -976,12 +982,13 @@ function saveNameToExportMap(
976982 * Takes a list of local names and indices and pushes the resolved local variable values
977983 * to LViewData in the same order as they are loaded in the template with load().
978984 */
979- function saveResolvedLocalsInData ( ) : void {
980- const localNames = previousOrParentNode . tNode . localNames ;
985+ function saveResolvedLocalsInData (
986+ lNode : LNodeWithLocalRefs , localRefExtractor : LocalRefExtractor ) : void {
987+ const localNames = lNode . tNode . localNames ;
981988 if ( localNames ) {
982989 for ( let i = 0 ; i < localNames . length ; i += 2 ) {
983990 const index = localNames [ i + 1 ] as number ;
984- const value = index === - 1 ? previousOrParentNode . native : directives ! [ index ] ;
991+ const value = index === - 1 ? localRefExtractor ( lNode ) : directives ! [ index ] ;
985992 viewData . push ( value ) ;
986993 }
987994 }
@@ -1838,18 +1845,21 @@ export function createLContainer(
18381845 * @param tagName The name of the container element, if applicable
18391846 * @param attrs The attrs attached to the container, if applicable
18401847 * @param localRefs A set of local reference bindings on the element.
1848+ * @param localRefExtractor A function which extracts local-refs values from the template.
1849+ * Defaults to the current element associated with the local-ref.
18411850 */
18421851export function template (
18431852 index : number , templateFn : ComponentTemplate < any > | null , tagName ?: string | null ,
1844- attrs ?: TAttributes | null , localRefs ?: string [ ] | null ) {
1853+ attrs ?: TAttributes | null , localRefs ?: string [ ] | null ,
1854+ localRefExtractor ?: LocalRefExtractor ) {
18451855 // TODO: consider a separate node type for templates
18461856 const node = containerInternal ( index , tagName || null , attrs || null , localRefs || null ) ;
18471857 if ( firstTemplatePass ) {
18481858 node . tNode . tViews =
18491859 createTView ( - 1 , templateFn , tView . directiveRegistry , tView . pipeRegistry , null ) ;
18501860 }
18511861
1852- createDirectivesAndLocals ( localRefs ) ;
1862+ createDirectivesAndLocals ( node , localRefs , localRefExtractor ) ;
18531863 currentQueries && ( currentQueries = currentQueries . addNode ( node ) ) ;
18541864 queueLifecycleHooks ( node . tNode . flags , tView ) ;
18551865 isParent = false ;
0 commit comments