MCPcopy Create free account
hub / github.com/angular/angular / lookupTokenUsingEmbeddedInjector

Function lookupTokenUsingEmbeddedInjector

packages/core/src/render3/di.ts:968–1038  ·  view source on GitHub ↗

* Returns a value from the closest embedded or node injector. * * @param tNode The Node where the search for the injector should start * @param lView The `LView` that contains the `tNode` * @param token The token to look for * @param flags Injection flags * @param notFoundValue The value to re

(
  tNode: TDirectiveHostNode,
  lView: LView,
  token: ProviderToken<T>,
  flags: InternalInjectFlags,
  notFoundValue?: any,
)

Source from the content-addressed store, hash-verified

966 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
967 */
968function lookupTokenUsingEmbeddedInjector<T>(
969 tNode: TDirectiveHostNode,
970 lView: LView,
971 token: ProviderToken<T>,
972 flags: InternalInjectFlags,
973 notFoundValue?: any,
974) {
975 let currentTNode: TDirectiveHostNode | null = tNode;
976 let currentLView: LView | null = lView;
977
978 // When an LView with an embedded view injector is inserted, it'll likely be interlaced with
979 // nodes who may have injectors (e.g. node injector -> embedded view injector -> node injector).
980 // Since the bloom filters for the node injectors have already been constructed and we don't
981 // have a way of extracting the records from an injector, the only way to maintain the correct
982 // hierarchy when resolving the value is to walk it node-by-node while attempting to resolve
983 // the token at each level.
984 while (
985 currentTNode !== null &&
986 currentLView !== null &&
987 currentLView[FLAGS] & LViewFlags.HasEmbeddedViewInjector &&
988 !isRootView(currentLView)
989 ) {
990 ngDevMode && assertTNodeForLView(currentTNode, currentLView);
991
992 // Note that this lookup on the node injector is using the `Self` flag, because
993 // we don't want the node injector to look at any parent injectors since we
994 // may hit the embedded view injector first.
995 const nodeInjectorValue = lookupTokenUsingNodeInjector(
996 currentTNode,
997 currentLView,
998 token,
999 flags | InternalInjectFlags.Self,
1000 NOT_FOUND,
1001 );
1002 if (nodeInjectorValue !== NOT_FOUND) {
1003 return nodeInjectorValue;
1004 }
1005
1006 // Has an explicit type due to a TS bug: https://github.com/microsoft/TypeScript/issues/33191
1007 let parentTNode: TElementNode | TContainerNode | null = currentTNode.parent;
1008
1009 // `TNode.parent` includes the parent within the current view only. If it doesn't exist,
1010 // it means that we've hit the view boundary and we need to go up to the next view.
1011 if (!parentTNode) {
1012 // Before we go to the next LView, check if the token exists on the current embedded injector.
1013 const embeddedViewInjector = currentLView[EMBEDDED_VIEW_INJECTOR];
1014 if (embeddedViewInjector) {
1015 const embeddedViewInjectorValue = (embeddedViewInjector as BackwardsCompatibleInjector).get(
1016 token,
1017 NOT_FOUND as T | {},
1018 // The `SkipSelf` flag is intended for the current injection context (the child component).
1019 // When we delegate to the embedded view injector, we are effectively traversing to a
1020 // parent/fallback scope, so the "Self" has already been skipped. We must strip the
1021 // flag to ensure the embedded view injector can resolve tokens from itself.
1022 flags & ~InternalInjectFlags.SkipSelf,
1023 );
1024 if (embeddedViewInjectorValue !== NOT_FOUND) {
1025 return embeddedViewInjectorValue;

Callers 1

getOrCreateInjectableFunction · 0.85

Calls 5

isRootViewFunction · 0.90
assertTNodeForLViewFunction · 0.90
getTNodeFromLViewFunction · 0.85
getMethod · 0.65

Tested by

no test coverage detected