MCPcopy Index your code
hub / github.com/angular/angular / lookupTokenUsingEmbeddedInjector

Function lookupTokenUsingEmbeddedInjector

packages/core/src/render3/di.ts:971–1041  ·  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

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

Used in the wild real call sites across dependent graphs

searching dependent graphs…