@@ -31,6 +31,7 @@ import {
3131 FLAGS ,
3232 HEADER_OFFSET ,
3333 HOST ,
34+ INJECTOR ,
3435 LView ,
3536 LViewFlags ,
3637 NEXT ,
@@ -41,6 +42,7 @@ import {
4142import { assertTNodeType } from './node_assert' ;
4243import { destroyLView , removeViewFromDOM } from './node_manipulation' ;
4344import { RendererFactory } from './interfaces/renderer' ;
45+ import { NgZone } from '../zone' ;
4446
4547/**
4648 * Replaces the metadata of a component type and re-renders all live instances of the component.
@@ -149,51 +151,60 @@ function recreateLView(
149151 const tNode = lView [ T_HOST ] as TElementNode ;
150152 ngDevMode && assertTNodeType ( tNode , TNodeType . Element ) ;
151153 ngDevMode && assertNotEqual ( newDef , oldDef , 'Expected different component definition' ) ;
154+ const zone = lView [ INJECTOR ] . get ( NgZone , null ) ;
155+ const recreate = ( ) => {
156+ // Recreate the TView since the template might've changed.
157+ const newTView = getOrCreateComponentTView ( newDef ) ;
152158
153- // Recreate the TView since the template might've changed.
154- const newTView = getOrCreateComponentTView ( newDef ) ;
159+ // Always force the creation of a new renderer to ensure state captured during construction
160+ // stays consistent with the new component definition by clearing any old cached factories.
161+ const rendererFactory = lView [ ENVIRONMENT ] . rendererFactory ;
162+ clearRendererCache ( rendererFactory , oldDef ) ;
155163
156- // Always force the creation of a new renderer to ensure state captured during construction
157- // stays consistent with the new component definition by clearing any old cached factories.
158- const rendererFactory = lView [ ENVIRONMENT ] . rendererFactory ;
159- clearRendererCache ( rendererFactory , oldDef ) ;
164+ // Create a new LView from the new TView, but reusing the existing TNode and DOM node.
165+ const newLView = createLView (
166+ parentLView ,
167+ newTView ,
168+ instance ,
169+ getInitialLViewFlagsFromDef ( newDef ) ,
170+ host ,
171+ tNode ,
172+ null ,
173+ rendererFactory . createRenderer ( host , newDef ) ,
174+ null ,
175+ null ,
176+ null ,
177+ ) ;
160178
161- // Create a new LView from the new TView, but reusing the existing TNode and DOM node.
162- const newLView = createLView (
163- parentLView ,
164- newTView ,
165- instance ,
166- getInitialLViewFlagsFromDef ( newDef ) ,
167- host ,
168- tNode ,
169- null ,
170- rendererFactory . createRenderer ( host , newDef ) ,
171- null ,
172- null ,
173- null ,
174- ) ;
179+ // Detach the LView from its current place in the tree so we don't
180+ // start traversing any siblings and modifying their structure.
181+ replaceLViewInTree ( parentLView , lView , newLView , tNode . index ) ;
175182
176- // Detach the LView from its current place in the tree so we don't
177- // start traversing any siblings and modifying their structure.
178- replaceLViewInTree ( parentLView , lView , newLView , tNode . index ) ;
183+ // Destroy the detached LView.
184+ destroyLView ( lView [ TVIEW ] , lView ) ;
179185
180- // Destroy the detached LView.
181- destroyLView ( lView [ TVIEW ] , lView ) ;
186+ // Remove the nodes associated with the destroyed LView. This removes the
187+ // descendants, but not the host which we want to stay in place.
188+ removeViewFromDOM ( lView [ TVIEW ] , lView ) ;
182189
183- // Remove the nodes associated with the destroyed LView. This removes the
184- // descendants, but not the host which we want to stay in place.
185- removeViewFromDOM ( lView [ TVIEW ] , lView ) ;
190+ // Reset the content projection state of the TNode before the first render.
191+ // Note that this has to happen after the LView has been destroyed or we
192+ // risk some projected nodes not being removed correctly.
193+ resetProjectionState ( tNode ) ;
186194
187- // Reset the content projection state of the TNode before the first render.
188- // Note that this has to happen after the LView has been destroyed or we
189- // risk some projected nodes not being removed correctly.
190- resetProjectionState ( tNode ) ;
195+ // Creation pass for the new view.
196+ renderView ( newTView , newLView , instance ) ;
191197
192- // Creation pass for the new view.
193- renderView ( newTView , newLView , instance ) ;
198+ // Update pass for the new view.
199+ refreshView ( newTView , newLView , newTView . template , instance ) ;
200+ } ;
194201
195- // Update pass for the new view.
196- refreshView ( newTView , newLView , newTView . template , instance ) ;
202+ // The callback isn't guaranteed to be inside the Zone so we need to bring it in ourselves.
203+ if ( zone === null ) {
204+ recreate ( ) ;
205+ } else {
206+ zone . run ( recreate ) ;
207+ }
197208}
198209
199210/**
0 commit comments