MCPcopy
hub / github.com/angular/angular / retrieveHydrationInfoImpl

Function retrieveHydrationInfoImpl

packages/core/src/hydration/utils.ts:121–204  ·  view source on GitHub ↗
(
  rNode: RElement,
  injector: Injector,
  isRootView = false,
)

Source from the content-addressed store, hash-verified

119let _retrieveHydrationInfoImpl: typeof retrieveHydrationInfoImpl = () => null;
120
121export function retrieveHydrationInfoImpl(
122 rNode: RElement,
123 injector: Injector,
124 isRootView = false,
125): DehydratedView | null {
126 let nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
127 if (nghAttrValue == null) return null;
128
129 // For cases when a root component also acts as an anchor node for a ViewContainerRef
130 // (for example, when ViewContainerRef is injected in a root component), there is a need
131 // to serialize information about the component itself, as well as an LContainer that
132 // represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
133 // (1) hydration info for the root component itself and (2) hydration info for the
134 // ViewContainerRef instance (an LContainer). Each piece of information is included into
135 // the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
136 // Since we only have 1 root element, we encode both bits of info into a single string:
137 // ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
138 // and 25 is the `ngh` for a root view which holds LContainer).
139 const [componentViewNgh, rootViewNgh] = nghAttrValue.split('|');
140 nghAttrValue = isRootView ? rootViewNgh : componentViewNgh;
141 if (!nghAttrValue) return null;
142
143 // We've read one of the ngh ids, keep the remaining one, so that
144 // we can set it back on the DOM element.
145 const rootNgh = rootViewNgh ? `|${rootViewNgh}` : '';
146 const remainingNgh = isRootView ? componentViewNgh : rootNgh;
147
148 let data: SerializedView = {};
149 // An element might have an empty `ngh` attribute value (e.g. `<comp ngh="" />`),
150 // which means that no special annotations are required. Do not attempt to read
151 // from the TransferState in this case.
152 if (nghAttrValue !== '') {
153 const transferState = injector.get(TransferState, null, {optional: true});
154 if (transferState !== null) {
155 const nghData = transferState.get(NGH_DATA_KEY, []);
156
157 // The nghAttrValue is always a number referencing an index
158 // in the hydration TransferState data.
159 data = nghData[Number(nghAttrValue)];
160
161 // If the `ngh` attribute exists and has a non-empty value,
162 // the hydration info *must* be present in the TransferState.
163 // If there is no data for some reasons, this is an error.
164 ngDevMode && assertDefined(data, 'Unable to retrieve hydration info from the TransferState.');
165 }
166 }
167 const dehydratedView: DehydratedView = {
168 data,
169 firstChild: rNode.firstChild ?? null,
170 };
171
172 if (isRootView) {
173 // If there is hydration info present for the root view, it means that there was
174 // a ViewContainerRef injected in the root component. The root component host element
175 // acted as an anchor node in this scenario. As a result, the DOM nodes that represent
176 // embedded views in this ViewContainerRef are located as siblings to the host node,
177 // i.e. `<app-root /><#VIEW1><#VIEW2>...<!--container-->`. In this case, the current
178 // node becomes the first child of this root view and the next sibling is the first

Callers

nothing calls this directly

Calls 7

assertDefinedFunction · 0.90
setSegmentHeadFunction · 0.85
getAttributeMethod · 0.65
getMethod · 0.65
setAttributeMethod · 0.65
removeAttributeMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…