Skip to content
Browse files

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
  • Loading branch information
petebacondarwin authored and matsko committed Nov 26, 2019
1 parent b659aa3 commit 978b500961ecc9465eb019eeee02ca7614ae5acb
@@ -245,14 +245,16 @@ export function createContainerRef(
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', () => {

it('should do nothing when a view is re-inserted / moved at the same index', () => {
const fixture = TestBed.createComponent(ViewContainerRefApp);

const templates = fixture.componentInstance.vcrComp.templates.toArray();
const viewContainerRef = fixture.componentInstance.vcrComp.vcr;

const ref0 = viewContainerRef.createEmbeddedView(templates[0]);


// insert again at the same place but without specifying any index

describe('move', () => {

0 comments on commit 978b500

Please sign in to comment.
You can’t perform that action at this time.