mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
perf(table): leaking reference through mostRecentCellOutlet (#12269)
Fixes the table leaking out a reference to a cell outlet via the `CdkCellOutlet.mostRecentCellOutlet` after all tables have been destroyed. Fixes #12259.
This commit is contained in:
committed by
mmalerba
parent
441c98e838
commit
34a7e38214
+10
-1
@@ -14,6 +14,7 @@ import {
|
||||
IterableDiffer,
|
||||
IterableDiffers,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
SimpleChanges,
|
||||
TemplateRef,
|
||||
ViewContainerRef,
|
||||
@@ -207,7 +208,7 @@ export interface CdkCellOutletMultiRowContext<T> {
|
||||
* @docs-private
|
||||
*/
|
||||
@Directive({selector: '[cdkCellOutlet]'})
|
||||
export class CdkCellOutlet {
|
||||
export class CdkCellOutlet implements OnDestroy {
|
||||
/** The ordered list of cells to render within this outlet's view container */
|
||||
cells: CdkCellDef[];
|
||||
|
||||
@@ -226,6 +227,14 @@ export class CdkCellOutlet {
|
||||
constructor(public _viewContainer: ViewContainerRef) {
|
||||
CdkCellOutlet.mostRecentCellOutlet = this;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
// If this was the last outlet being rendered in the view, remove the reference
|
||||
// from the static property after it has been destroyed to avoid leaking memory.
|
||||
if (CdkCellOutlet.mostRecentCellOutlet === this) {
|
||||
CdkCellOutlet.mostRecentCellOutlet = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Header template container that contains the cell outlet. Adds the right class and role. */
|
||||
|
||||
@@ -14,7 +14,7 @@ import {BehaviorSubject, combineLatest, Observable, of as observableOf} from 'rx
|
||||
import {map} from 'rxjs/operators';
|
||||
import {CdkColumnDef} from './cell';
|
||||
import {CdkTableModule} from './index';
|
||||
import {CdkHeaderRowDef, CdkRowDef} from './row';
|
||||
import {CdkHeaderRowDef, CdkRowDef, CdkCellOutlet} from './row';
|
||||
import {CdkTable} from './table';
|
||||
import {
|
||||
getTableDuplicateColumnNameError,
|
||||
@@ -137,6 +137,17 @@ describe('CdkTable', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should clear the `mostRecentCellOutlet` on destroy', () => {
|
||||
// Note: we cast the assertions here to booleans, because they may
|
||||
// contain circular objects which will throw Jasmine into an infinite
|
||||
// when its tries to stringify them to show a test failure.
|
||||
expect(!!CdkCellOutlet.mostRecentCellOutlet).toBe(true);
|
||||
|
||||
fixture.destroy();
|
||||
|
||||
expect(!!CdkCellOutlet.mostRecentCellOutlet).toBe(false);
|
||||
});
|
||||
|
||||
describe('should correctly use the differ to add/remove/move rows', () => {
|
||||
function addInitialIndexAttribute() {
|
||||
// Each row receives an attribute 'initialIndex' the element's original place
|
||||
|
||||
Reference in New Issue
Block a user