diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts index 8b63e30d0c..a095dc47f5 100644 --- a/packages/core/src/render3/di.ts +++ b/packages/core/src/render3/di.ts @@ -19,7 +19,7 @@ import {getFactoryDef} from './definition'; import {NG_ELEMENT_ID, NG_FACTORY_DEF} from './fields'; import {DirectiveDef, FactoryFn} from './interfaces/definition'; import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags, TNODE, isFactory} from './interfaces/injector'; -import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeProviderIndexes, TNodeType} from './interfaces/node'; +import {AttributeMarker, TContainerNode, TDirectiveHostNode, TElementContainerNode, TElementNode, TNode, TNodeProviderIndexes, TNodeType} from './interfaces/node'; import {isComponentDef, isComponentHost} from './interfaces/type_checks'; import {DECLARATION_VIEW, INJECTOR, LView, TData, TVIEW, TView, T_HOST} from './interfaces/view'; import {assertNodeOfPossibleTypes} from './node_assert'; @@ -528,7 +528,7 @@ export function locateDirectiveOrProvider( * instantiates the `injectable` and caches the value. */ export function getNodeInjectable( - tData: TData, lView: LView, index: number, tNode: TElementNode): any { + tData: TData, lView: LView, index: number, tNode: TDirectiveHostNode): any { let value = lView[index]; if (isFactory(value)) { const factory: NodeInjectorFactory = value; diff --git a/packages/core/src/render3/di_setup.ts b/packages/core/src/render3/di_setup.ts index 7540090cba..9716a70fa1 100644 --- a/packages/core/src/render3/di_setup.ts +++ b/packages/core/src/render3/di_setup.ts @@ -15,7 +15,7 @@ import {diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode} f import {ɵɵdirectiveInject} from './instructions/all'; import {DirectiveDef} from './interfaces/definition'; import {NodeInjectorFactory} from './interfaces/injector'; -import {TContainerNode, TElementContainerNode, TElementNode, TNodeProviderIndexes} from './interfaces/node'; +import {TContainerNode, TDirectiveHostNode, TElementContainerNode, TElementNode, TNodeProviderIndexes} from './interfaces/node'; import {isComponentDef} from './interfaces/type_checks'; import {LView, TData, TVIEW, TView} from './interfaces/view'; import {getLView, getPreviousOrParentTNode} from './state'; @@ -205,7 +205,7 @@ function indexOf(item: any, arr: any[], begin: number, end: number) { */ function multiProvidersFactoryResolver( this: NodeInjectorFactory, _: undefined, tData: TData, lData: LView, - tNode: TElementNode): any[] { + tNode: TDirectiveHostNode): any[] { return multiResolve(this.multi !, []); } @@ -216,7 +216,7 @@ function multiProvidersFactoryResolver( */ function multiViewProvidersFactoryResolver( this: NodeInjectorFactory, _: undefined, tData: TData, lData: LView, - tNode: TElementNode): any[] { + tNode: TDirectiveHostNode): any[] { const factories = this.multi !; let result: any[]; if (this.providerFactory) { @@ -254,8 +254,8 @@ function multiResolve(factories: Array<() => any>, result: any[]): any[] { */ function multiFactory( factoryFn: ( - this: NodeInjectorFactory, _: undefined, tData: TData, lData: LView, tNode: TElementNode) => - any, + this: NodeInjectorFactory, _: undefined, tData: TData, lData: LView, + tNode: TDirectiveHostNode) => any, index: number, isViewProvider: boolean, isComponent: boolean, f: () => any): NodeInjectorFactory { const factory = new NodeInjectorFactory(factoryFn, isViewProvider, ɵɵdirectiveInject); diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index 5fa7c649b2..4852d490c1 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -23,7 +23,7 @@ import {executeCheckHooks, executeInitAndCheckHooks, incrementInitPhaseFlags, re import {ACTIVE_INDEX, CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/container'; import {ComponentDef, ComponentTemplate, DirectiveDef, DirectiveDefListOrFactory, PipeDefListOrFactory, RenderFlags, ViewQueriesFunction} from '../interfaces/definition'; import {INJECTOR_BLOOM_PARENT_SIZE, NodeInjectorFactory} from '../interfaces/injector'; -import {AttributeMarker, InitialInputData, InitialInputs, LocalRefExtractor, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TElementContainerNode, TElementNode, TIcuContainerNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType, TProjectionNode, TViewNode} from '../interfaces/node'; +import {AttributeMarker, InitialInputData, InitialInputs, LocalRefExtractor, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TDirectiveHostNode, TElementContainerNode, TElementNode, TIcuContainerNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType, TProjectionNode, TViewNode} from '../interfaces/node'; import {RComment, RElement, RText, Renderer3, RendererFactory3, isProceduralRenderer} from '../interfaces/renderer'; import {SanitizerFn} from '../interfaces/sanitization'; import {isComponentDef, isComponentHost, isContentQueryHost, isLContainer, isRootView} from '../interfaces/type_checks'; @@ -1090,19 +1090,19 @@ export function resolveDirectives( /** * Instantiate all the directives that were previously resolved on the current node. */ -function instantiateAllDirectives(tView: TView, lView: LView, tNode: TNode) { +function instantiateAllDirectives(tView: TView, lView: LView, tNode: TDirectiveHostNode) { const start = tNode.directiveStart; const end = tNode.directiveEnd; if (!tView.firstTemplatePass) { - getOrCreateNodeInjectorForNode( - tNode as TElementNode | TContainerNode | TElementContainerNode, lView); + getOrCreateNodeInjectorForNode(tNode, lView); } for (let i = start; i < end; i++) { const def = tView.data[i] as DirectiveDef; if (isComponentDef(def)) { - addComponentLogic(lView, tNode, def as ComponentDef); + assertNodeOfPossibleTypes(tNode, TNodeType.Element); + addComponentLogic(lView, tNode as TElementNode, def); } - const directive = getNodeInjectable(tView.data, lView !, i, tNode as TElementNode); + const directive = getNodeInjectable(tView.data, lView, i, tNode); postProcessDirective(lView, tNode, directive, def, i - start); } } @@ -1306,7 +1306,7 @@ function baseResolveDirective(tView: TView, viewData: LView, def: DirectiveDe viewData.push(nodeInjectorFactory); } -function addComponentLogic(lView: LView, hostTNode: TNode, def: ComponentDef): void { +function addComponentLogic(lView: LView, hostTNode: TElementNode, def: ComponentDef): void { const native = getNativeByTNode(hostTNode, lView) as RElement; const tView = getOrCreateTView(def); diff --git a/packages/core/src/render3/interfaces/injector.ts b/packages/core/src/render3/interfaces/injector.ts index ad2ef16d05..a432422539 100644 --- a/packages/core/src/render3/interfaces/injector.ts +++ b/packages/core/src/render3/interfaces/injector.ts @@ -10,7 +10,7 @@ import {InjectionToken} from '../../di/injection_token'; import {InjectFlags} from '../../di/interface/injector'; import {Type} from '../../interface/type'; -import {TElementNode} from './node'; +import {TDirectiveHostNode} from './node'; import {LView, TData} from './view'; export const TNODE = 8; @@ -230,7 +230,7 @@ export class NodeInjectorFactory { /** * The TNode of the same element injector. */ - tNode: TElementNode) => any, + tNode: TDirectiveHostNode) => any, /** * Set to `true` if the token is declared in `viewProviders` (or if it is component). */ diff --git a/packages/core/src/render3/interfaces/node.ts b/packages/core/src/render3/interfaces/node.ts index a598252390..352f6eaa6f 100644 --- a/packages/core/src/render3/interfaces/node.ts +++ b/packages/core/src/render3/interfaces/node.ts @@ -602,6 +602,11 @@ export interface TProjectionNode extends TNode { projection: number; } +/** + * An union type representing all TNode types that can host a directive. + */ +export type TDirectiveHostNode = TElementNode | TContainerNode | TElementContainerNode; + /** * This mapping is necessary so we can set input properties and output listeners * properly at runtime when property names are minified or aliased.