fix(ivy): prevent errors from views being destroyed twice (#28413)

Previously, attempting to destroy a view with listeners more than once
throws an error during event listener cleanup. This happens because
`cleanup` field on the `TView` has already been cleared out by the time
the second destruction runs.

The `destroyed` flag on LView was previously being set in the `destroyLView` function,
but this flag was never _checked_ anywhere in the codebase. This commit
moves _setting_ this flag to the `cleanupView` function, just before
destroy hooks are called. This is necessary because the destroy hooks
can contain arbitrary user code, such as (surprise!) attempting to
destroy the view (again). We also add a check to `destroyLView` to skip
already-destroyed views. This prevents the cleanup code path from running twice.

PR Close #28413
This commit is contained in:
Jeremy Elbourn
2019-01-28 15:23:53 -08:00
committed by Matias Niemelä
parent b35ef184a7
commit 35e45dc894
3 changed files with 79 additions and 12 deletions

View File

@ -180,7 +180,12 @@ export class ComponentFixture<T> extends BaseFixture {
}
destroy(): void {
this.containerElement.removeChild(this.hostElement);
// Skip removing the DOM element if it has already been removed (the view has already
// been destroyed).
if (this.hostElement.parentNode === this.containerElement) {
this.containerElement.removeChild(this.hostElement);
}
destroyLView(getRootView(this.component));
}
}