Initializes the data structures necessary for a list of directives to be instantiated.
(
tView: TView,
lView: LView<unknown>,
tNode: TElementNode | TContainerNode | TElementContainerNode,
directives: DirectiveDef<unknown>[],
exportsMap: {[key: string]: number} | null,
hostDirectiveDefs: HostDirectiveDefs | null,
hostDirectiveRanges: HostDirectiveRanges | null,
)
| 134 | |
| 135 | /** Initializes the data structures necessary for a list of directives to be instantiated. */ |
| 136 | function initializeDirectives( |
| 137 | tView: TView, |
| 138 | lView: LView<unknown>, |
| 139 | tNode: TElementNode | TContainerNode | TElementContainerNode, |
| 140 | directives: DirectiveDef<unknown>[], |
| 141 | exportsMap: {[key: string]: number} | null, |
| 142 | hostDirectiveDefs: HostDirectiveDefs | null, |
| 143 | hostDirectiveRanges: HostDirectiveRanges | null, |
| 144 | ) { |
| 145 | ngDevMode && assertFirstCreatePass(tView); |
| 146 | |
| 147 | const directivesLength = directives.length; |
| 148 | let componentDef: ComponentDef<unknown> | null = null; |
| 149 | |
| 150 | // Publishes the directive types to DI so they can be injected. Needs to |
| 151 | // happen in a separate pass before the TNode flags have been initialized. |
| 152 | for (let i = 0; i < directivesLength; i++) { |
| 153 | const def = directives[i]; |
| 154 | if (componentDef === null && isComponentDef(def)) { |
| 155 | componentDef = def; |
| 156 | markAsComponentHost(tView, tNode, i); |
| 157 | } |
| 158 | diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, def.type); |
| 159 | } |
| 160 | |
| 161 | initTNodeFlags(tNode, tView.data.length, directivesLength); |
| 162 | |
| 163 | // When the same token is provided by several directives on the same node, some rules apply in |
| 164 | // the viewEngine: |
| 165 | // - viewProviders have priority over providers |
| 166 | // - the last directive in NgModule.declarations has priority over the previous one |
| 167 | // So to match these rules, the order in which providers are added in the arrays is very |
| 168 | // important. |
| 169 | if (componentDef?.viewProvidersResolver) { |
| 170 | // Only components can have `viewProviders`, `viewProviders` are registered first and there |
| 171 | // can only be one component so we check for it specifically. |
| 172 | componentDef.viewProvidersResolver(componentDef); |
| 173 | } |
| 174 | |
| 175 | for (let i = 0; i < directivesLength; i++) { |
| 176 | const def = directives[i]; |
| 177 | if (def.providersResolver) { |
| 178 | def.providersResolver(def); |
| 179 | } |
| 180 | } |
| 181 | let preOrderHooksFound = false; |
| 182 | let preOrderCheckHooksFound = false; |
| 183 | let directiveIdx = allocExpando(tView, lView, directivesLength, null); |
| 184 | ngDevMode && |
| 185 | assertSame( |
| 186 | directiveIdx, |
| 187 | tNode.directiveStart, |
| 188 | 'TNode.directiveStart should point to just allocated space', |
| 189 | ); |
| 190 | |
| 191 | // If there's at least one directive, we'll have to track it so initialize the map. |
| 192 | if (directivesLength > 0) { |
| 193 | tNode.directiveToIndex = new Map(); |
no test coverage detected
searching dependent graphs…