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

Function recreateLView

packages/core/src/render3/hmr.ts:229–324  ·  view source on GitHub ↗

* Recreates an LView in-place from a new component definition. * @param importMeta `import.meta` information. * @param id HMR ID for the component. * @param newDef Definition from which to recreate the view. * @param oldDef Previous component definition being swapped out. * @param lView View to

(
  importMeta: ImportMetaExtended | null,
  id: string | null,
  newDef: ComponentDef<unknown>,
  oldDef: ComponentDef<unknown>,
  lView: LView<unknown>,
)

Source from the content-addressed store, hash-verified

227 * @param lView View to be recreated.
228 */
229function recreateLView(
230 importMeta: ImportMetaExtended | null,
231 id: string | null,
232 newDef: ComponentDef<unknown>,
233 oldDef: ComponentDef<unknown>,
234 lView: LView<unknown>,
235): void {
236 const instance = lView[CONTEXT];
237 let host = lView[HOST]! as HTMLElement;
238 // In theory the parent can also be an LContainer, but it appears like that's
239 // only the case for embedded views which we won't be replacing here.
240 const parentLView = lView[PARENT] as LView;
241 ngDevMode && assertLView(parentLView);
242 const tNode = lView[T_HOST] as TElementNode;
243 ngDevMode && assertTNodeType(tNode, TNodeType.Element);
244 ngDevMode && assertNotEqual(newDef, oldDef, 'Expected different component definition');
245 const zone = lView[INJECTOR].get(NgZone, null);
246 const recreate = () => {
247 // If we're recreating a component with shadow DOM encapsulation, it will have attached a
248 // shadow root. The browser will throw if we attempt to attach another one and there's no way
249 // to detach it. Our only option is to make a clone only of the root node, replace the node
250 // with the clone and use it for the newly-created LView.
251 if (
252 oldDef.encapsulation === ViewEncapsulation.ShadowDom ||
253 oldDef.encapsulation === ViewEncapsulation.ExperimentalIsolatedShadowDom
254 ) {
255 const newHost = host.cloneNode(false) as HTMLElement;
256 host.replaceWith(newHost);
257 host = newHost;
258 }
259
260 // Recreate the TView since the template might've changed.
261 const newTView = getOrCreateComponentTView(newDef);
262
263 // Create a new LView from the new TView, but reusing the existing TNode and DOM node.
264 const newLView = createLView(
265 parentLView,
266 newTView,
267 instance,
268 getInitialLViewFlagsFromDef(newDef),
269 host,
270 tNode,
271 null,
272 null, // The renderer will be created a bit further down once the old one is destroyed.
273 null,
274 null,
275 null,
276 );
277
278 // Detach the LView from its current place in the tree so we don't
279 // start traversing any siblings and modifying their structure.
280 replaceLViewInTree(parentLView, lView, newLView, tNode.index);
281
282 // Destroy the detached LView.
283 destroyLView(lView[TVIEW], lView);
284
285 // Clean up any dehydrated views left over from SSR hydration.
286 // Neither destroyLView nor removeViewFromDOM handle DOM nodes

Callers 1

recreateMatchingLViewsFunction · 0.85

Calls 6

assertLViewFunction · 0.90
assertTNodeTypeFunction · 0.90
assertNotEqualFunction · 0.90
getMethod · 0.65
runMethod · 0.65

Tested by

no test coverage detected