()
| 242 | ngDevMode && assertNotEqual(newDef, oldDef, 'Expected different component definition'); |
| 243 | const zone = lView[INJECTOR].get(NgZone, null); |
| 244 | const recreate = () => { |
| 245 | // If we're recreating a component with shadow DOM encapsulation, it will have attached a |
| 246 | // shadow root. The browser will throw if we attempt to attach another one and there's no way |
| 247 | // to detach it. Our only option is to make a clone only of the root node, replace the node |
| 248 | // with the clone and use it for the newly-created LView. |
| 249 | if ( |
| 250 | oldDef.encapsulation === ViewEncapsulation.ShadowDom || |
| 251 | oldDef.encapsulation === ViewEncapsulation.ExperimentalIsolatedShadowDom |
| 252 | ) { |
| 253 | const newHost = host.cloneNode(false) as HTMLElement; |
| 254 | host.replaceWith(newHost); |
| 255 | host = newHost; |
| 256 | } |
| 257 | |
| 258 | // Recreate the TView since the template might've changed. |
| 259 | const newTView = getOrCreateComponentTView(newDef); |
| 260 | |
| 261 | // Create a new LView from the new TView, but reusing the existing TNode and DOM node. |
| 262 | const newLView = createLView( |
| 263 | parentLView, |
| 264 | newTView, |
| 265 | instance, |
| 266 | getInitialLViewFlagsFromDef(newDef), |
| 267 | host, |
| 268 | tNode, |
| 269 | null, |
| 270 | null, // The renderer will be created a bit further down once the old one is destroyed. |
| 271 | null, |
| 272 | null, |
| 273 | null, |
| 274 | ); |
| 275 | |
| 276 | // Detach the LView from its current place in the tree so we don't |
| 277 | // start traversing any siblings and modifying their structure. |
| 278 | replaceLViewInTree(parentLView, lView, newLView, tNode.index); |
| 279 | |
| 280 | // Destroy the detached LView. |
| 281 | destroyLView(lView[TVIEW], lView); |
| 282 | |
| 283 | // Clean up any dehydrated views left over from SSR hydration. |
| 284 | // Neither destroyLView nor removeViewFromDOM handle DOM nodes |
| 285 | // stored in LContainer[DEHYDRATED_VIEWS], which causes duplicated |
| 286 | // content when the view is re-rendered during HMR. |
| 287 | cleanupDehydratedLView(lView); |
| 288 | |
| 289 | // Always force the creation of a new renderer to ensure state captured during construction |
| 290 | // stays consistent with the new component definition by clearing any old ached factories. |
| 291 | const rendererFactory = lView[ENVIRONMENT].rendererFactory; |
| 292 | clearRendererCache(rendererFactory, oldDef); |
| 293 | |
| 294 | // Patch a brand-new renderer onto the new view only after the old |
| 295 | // view is destroyed so that the runtime doesn't try to reuse it. |
| 296 | newLView[RENDERER] = rendererFactory.createRenderer(host, newDef); |
| 297 | |
| 298 | // Remove the nodes associated with the destroyed LView. This removes the |
| 299 | // descendants, but not the host which we want to stay in place. |
| 300 | removeViewFromDOM(lView[TVIEW], lView); |
| 301 |
nothing calls this directly
no test coverage detected
searching dependent graphs…