fix(ivy): support inserting a `viewRef` that is already present (#34052)
When inserting a `viewRef` it is possible to not provide an `index`, which is regarded as appending to the end of the container. If the `viewRef` already exists in the container, then this results in a move. But there was a fault in the logic that computed where to insert the `viewRef` that did not account for the fact that the `viewRef` was already in the container, so the insertion `index` was outside the bounds of the array. Fixes #33924 PR Close #34052
This commit is contained in:
parent
5de7960f01
commit
f0f426b2d0
|
@ -245,14 +245,16 @@ export function createContainerRef(
|
|||
}
|
||||
this.allocateContainerIfNeeded();
|
||||
const lView = (viewRef as ViewRef<any>)._lView !;
|
||||
const adjustedIdx = this._adjustIndex(index);
|
||||
|
||||
if (viewAttachedToContainer(lView)) {
|
||||
// If view is already attached, fall back to move() so we clean up
|
||||
// references appropriately.
|
||||
return this.move(viewRef, adjustedIdx);
|
||||
// Note that we "shift" -1 because the move will involve inserting
|
||||
// one view but also removing one view.
|
||||
return this.move(viewRef, this._adjustIndex(index, -1));
|
||||
}
|
||||
|
||||
const adjustedIdx = this._adjustIndex(index);
|
||||
insertView(lView, this._lContainer, adjustedIdx);
|
||||
|
||||
const beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer);
|
||||
|
|
|
@ -204,6 +204,22 @@ describe('ViewContainerRef', () => {
|
|||
expect(fixture.nativeElement.textContent).toEqual('102');
|
||||
}
|
||||
});
|
||||
|
||||
it('should do nothing when a view is re-inserted / moved at the same index', () => {
|
||||
const fixture = TestBed.createComponent(ViewContainerRefApp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const templates = fixture.componentInstance.vcrComp.templates.toArray();
|
||||
const viewContainerRef = fixture.componentInstance.vcrComp.vcr;
|
||||
|
||||
const ref0 = viewContainerRef.createEmbeddedView(templates[0]);
|
||||
|
||||
expect(fixture.nativeElement.textContent).toEqual('0');
|
||||
|
||||
// insert again at the same place but without specifying any index
|
||||
viewContainerRef.insert(ref0);
|
||||
expect(fixture.nativeElement.textContent).toEqual('0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('move', () => {
|
||||
|
|
Loading…
Reference in New Issue