fix(ivy): attempting to remove detached view on destroy (#27585)
Currently the `ViewRef.destroy` method assumes that its index inside the view container will always be valid, however if it has been removed already, it'll be -1 which will throw an error. The error manifested itself in one of the unit tests where a view had been detached during the test and then `TestBed` attempted to destroy its `ComponentRef` which ended threw an `Error during cleanup of component`. PR Close #27585
This commit is contained in:
parent
d32939d51a
commit
5d34657198
|
@ -60,8 +60,13 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
if (this._appRef) {
|
if (this._appRef) {
|
||||||
this._appRef.detachView(this);
|
this._appRef.detachView(this);
|
||||||
} else if (this._viewContainerRef && viewAttached(this._lView)) {
|
} else if (this._viewContainerRef) {
|
||||||
this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
|
const index = this._viewContainerRef.indexOf(this);
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
this._viewContainerRef.detach(index);
|
||||||
|
}
|
||||||
|
|
||||||
this._viewContainerRef = null;
|
this._viewContainerRef = null;
|
||||||
}
|
}
|
||||||
destroyLView(this._lView);
|
destroyLView(this._lView);
|
||||||
|
|
|
@ -19,7 +19,6 @@ import {pipe, pipeBind1} from '../../src/render3/pipe';
|
||||||
import {getLView} from '../../src/render3/state';
|
import {getLView} from '../../src/render3/state';
|
||||||
import {getNativeByIndex} from '../../src/render3/util';
|
import {getNativeByIndex} from '../../src/render3/util';
|
||||||
import {NgForOf} from '../../test/render3/common_with_def';
|
import {NgForOf} from '../../test/render3/common_with_def';
|
||||||
import {fixmeIvy} from '@angular/private/testing';
|
|
||||||
|
|
||||||
import {getRendererFactory2} from './imported_renderer2';
|
import {getRendererFactory2} from './imported_renderer2';
|
||||||
import {ComponentFixture, TemplateFixture, createComponent, getDirectiveOnNode} from './render_util';
|
import {ComponentFixture, TemplateFixture, createComponent, getDirectiveOnNode} from './render_util';
|
||||||
|
@ -1099,6 +1098,19 @@ describe('ViewContainerRef', () => {
|
||||||
expect(dynamicComp.doCheckCount).toEqual(1);
|
expect(dynamicComp.doCheckCount).toEqual(1);
|
||||||
expect(changeDetector.context).toEqual(dynamicComp);
|
expect(changeDetector.context).toEqual(dynamicComp);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not throw when destroying a reattached component', () => {
|
||||||
|
const fixture = new ComponentFixture(AppComp);
|
||||||
|
|
||||||
|
const dynamicCompFactory = fixture.component.cfr.resolveComponentFactory(DynamicComp);
|
||||||
|
const ref = fixture.component.vcr.createComponent(dynamicCompFactory);
|
||||||
|
fixture.update();
|
||||||
|
|
||||||
|
fixture.component.vcr.detach(fixture.component.vcr.indexOf(ref.hostView));
|
||||||
|
|
||||||
|
expect(() => { ref.destroy(); }).not.toThrow();
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
class EmbeddedComponentWithNgContent {
|
class EmbeddedComponentWithNgContent {
|
||||||
|
|
Loading…
Reference in New Issue