@@ -1204,8 +1204,9 @@ export function containerRefreshEnd(): void {
1204
1204
container . native = undefined ;
1205
1205
ngDevMode && assertNodeType ( container , LNodeFlags . Container ) ;
1206
1206
const nextIndex = container . data . nextIndex ;
1207
+
1208
+ // remove extra views at the end of the container
1207
1209
while ( nextIndex < container . data . views . length ) {
1208
- // remove extra view.
1209
1210
removeView ( container , nextIndex ) ;
1210
1211
}
1211
1212
}
@@ -1222,6 +1223,35 @@ function refreshDynamicChildren() {
1222
1223
}
1223
1224
}
1224
1225
1226
+ /**
1227
+ * Looks for a view with a given view block id inside a provided LContainer.
1228
+ * Removes views that need to be deleted in the process.
1229
+ *
1230
+ * @param containerNode where to search for views
1231
+ * @param startIdx starting index in the views array to search from
1232
+ * @param viewBlockId exact view block id to look for
1233
+ * @returns index of a found view or -1 if not found
1234
+ */
1235
+ function scanForView (
1236
+ containerNode : LContainerNode , startIdx : number , viewBlockId : number ) : LViewNode | null {
1237
+ const views = containerNode . data . views ;
1238
+ for ( let i = startIdx ; i < views . length ; i ++ ) {
1239
+ const viewAtPositionId = views [ i ] . data . id ;
1240
+ if ( viewAtPositionId === viewBlockId ) {
1241
+ return views [ i ] ;
1242
+ } else if ( viewAtPositionId < viewBlockId ) {
1243
+ // found a view that should not be at this position - remove
1244
+ removeView ( containerNode , i ) ;
1245
+ } else {
1246
+ // found a view with id grater than the one we are searching for
1247
+ // which means that required view doesn't exist and can't be found at
1248
+ // later positions in the views array - stop the search here
1249
+ break ;
1250
+ }
1251
+ }
1252
+ return null ;
1253
+ }
1254
+
1225
1255
/**
1226
1256
* Marks the start of an embedded view.
1227
1257
*
@@ -1233,17 +1263,13 @@ export function embeddedViewStart(viewBlockId: number): boolean {
1233
1263
( isParent ? previousOrParentNode : previousOrParentNode . parent ! ) as LContainerNode ;
1234
1264
ngDevMode && assertNodeType ( container , LNodeFlags . Container ) ;
1235
1265
const lContainer = container . data ;
1236
- const views = lContainer . views ;
1266
+ const existingViewNode = scanForView ( container , lContainer . nextIndex , viewBlockId ) ;
1237
1267
1238
- const existingView : LViewNode | false =
1239
- ! creationMode && lContainer . nextIndex < views . length && views [ lContainer . nextIndex ] ;
1240
- let viewUpdateMode = existingView && viewBlockId === ( existingView as LViewNode ) . data . id ;
1241
-
1242
- if ( viewUpdateMode ) {
1243
- previousOrParentNode = views [ lContainer . nextIndex ++ ] ;
1268
+ if ( existingViewNode ) {
1269
+ previousOrParentNode = existingViewNode ;
1244
1270
ngDevMode && assertNodeType ( previousOrParentNode , LNodeFlags . View ) ;
1245
1271
isParent = true ;
1246
- enterView ( ( existingView as LViewNode ) . data , previousOrParentNode as LViewNode ) ;
1272
+ enterView ( ( existingViewNode as LViewNode ) . data , existingViewNode as LViewNode ) ;
1247
1273
} else {
1248
1274
// When we create a new LView, we always reset the state of the instructions.
1249
1275
const newView = createLView (
@@ -1254,10 +1280,9 @@ export function embeddedViewStart(viewBlockId: number): boolean {
1254
1280
}
1255
1281
1256
1282
enterView ( newView , createLNode ( null , LNodeFlags . View , null , newView ) ) ;
1257
- lContainer . nextIndex ++ ;
1258
1283
}
1259
1284
1260
- return ! viewUpdateMode ;
1285
+ return ! existingViewNode ;
1261
1286
}
1262
1287
1263
1288
/**
@@ -1286,19 +1311,18 @@ export function embeddedViewEnd(): void {
1286
1311
refreshChildComponents ( ) ;
1287
1312
isParent = false ;
1288
1313
const viewNode = previousOrParentNode = currentView . node as LViewNode ;
1289
- const container = previousOrParentNode . parent as LContainerNode ;
1290
- if ( container ) {
1314
+ const containerNode = previousOrParentNode . parent as LContainerNode ;
1315
+ if ( containerNode ) {
1291
1316
ngDevMode && assertNodeType ( viewNode , LNodeFlags . View ) ;
1292
- ngDevMode && assertNodeType ( container , LNodeFlags . Container ) ;
1293
- const containerState = container . data ;
1294
- const previousView = containerState . nextIndex <= containerState . views . length ?
1295
- containerState . views [ containerState . nextIndex - 1 ] as LViewNode :
1296
- null ;
1297
- const viewIdChanged = previousView == null ? true : previousView . data . id !== viewNode . data . id ;
1298
-
1299
- if ( viewIdChanged ) {
1300
- insertView ( container , viewNode , containerState . nextIndex - 1 ) ;
1317
+ ngDevMode && assertNodeType ( containerNode , LNodeFlags . Container ) ;
1318
+ const lContainer = containerNode . data ;
1319
+
1320
+ if ( creationMode ) {
1321
+ // it is a new view, insert it into collection of views for a given container
1322
+ insertView ( containerNode , viewNode , lContainer . nextIndex ) ;
1301
1323
}
1324
+
1325
+ lContainer . nextIndex ++ ;
1302
1326
}
1303
1327
leaveView ( currentView ! . parent ! ) ;
1304
1328
ngDevMode && assertEqual ( isParent , false , 'isParent' ) ;
0 commit comments