diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts index 114da2fbc634..58f2ae4b53b9 100644 --- a/src/cdk/table/table.ts +++ b/src/cdk/table/table.ts @@ -40,6 +40,7 @@ import { IterableChangeRecord, IterableDiffer, IterableDiffers, + NgZone, OnDestroy, OnInit, Optional, @@ -60,7 +61,7 @@ import { Subject, Subscription, } from 'rxjs'; -import {takeUntil} from 'rxjs/operators'; +import {take, takeUntil} from 'rxjs/operators'; import {CdkColumnDef} from './cell'; import {_CoalescedStyleScheduler, _COALESCED_STYLE_SCHEDULER} from './coalesced-style-scheduler'; import { @@ -525,6 +526,12 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes @SkipSelf() @Inject(STICKY_POSITIONING_LISTENER) protected readonly _stickyPositioningListener: StickyPositioningListener, + /** + * @deprecated `_ngZone` parameter to become required. + * @breaking-change 14.0.0 + */ + @Optional() + protected readonly _ngZone: NgZone, ) { if (!role) { this._elementRef.nativeElement.setAttribute('role', 'table'); @@ -666,7 +673,16 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes }); this._updateNoDataRow(); - this.updateStickyColumnStyles(); + + // Allow the new row data to render before measuring it. + // @breaking-change 14.0.0 Remove undefined check once _ngZone is required. + if (this._ngZone && NgZone.isInAngularZone()) { + this._ngZone.onStable.pipe(take(1), takeUntil(this._onDestroy)).subscribe(() => { + this.updateStickyColumnStyles(); + }); + } else { + this.updateStickyColumnStyles(); + } this.contentChanged.next(); } diff --git a/tools/public_api_guard/cdk/table.md b/tools/public_api_guard/cdk/table.md index 8d459ff891f3..fe96883367fd 100644 --- a/tools/public_api_guard/cdk/table.md +++ b/tools/public_api_guard/cdk/table.md @@ -297,7 +297,8 @@ export class CdkRowDef extends BaseRowDef { // @public export class CdkTable implements AfterContentChecked, CollectionViewer, OnDestroy, OnInit { constructor(_differs: IterableDiffers, _changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, role: string, _dir: Directionality, _document: any, _platform: Platform, _viewRepeater: _ViewRepeater, RowContext>, _coalescedStyleScheduler: _CoalescedStyleScheduler, _viewportRuler: ViewportRuler, - _stickyPositioningListener: StickyPositioningListener); + _stickyPositioningListener: StickyPositioningListener, + _ngZone: NgZone); addColumnDef(columnDef: CdkColumnDef): void; addFooterRowDef(footerRowDef: CdkFooterRowDef): void; addHeaderRowDef(headerRowDef: CdkHeaderRowDef): void; @@ -344,6 +345,8 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes ngOnDestroy(): void; // (undocumented) ngOnInit(): void; + // @deprecated (undocumented) + protected readonly _ngZone: NgZone; _noDataRow: CdkNoDataRow; // (undocumented) _noDataRowOutlet: NoDataRowOutlet; @@ -372,7 +375,7 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes // (undocumented) static ɵcmp: i0.ɵɵComponentDeclaration, "cdk-table, table[cdk-table]", ["cdkTable"], { "trackBy": "trackBy"; "dataSource": "dataSource"; "multiTemplateDataRows": "multiTemplateDataRows"; "fixedLayout": "fixedLayout"; }, { "contentChanged": "contentChanged"; }, ["_noDataRow", "_contentColumnDefs", "_contentRowDefs", "_contentHeaderRowDefs", "_contentFooterRowDefs"], ["caption", "colgroup, col"]>; // (undocumented) - static ɵfac: i0.ɵɵFactoryDeclaration, [null, null, null, { attribute: "role"; }, { optional: true; }, null, null, null, null, null, { optional: true; skipSelf: true; }]>; + static ɵfac: i0.ɵɵFactoryDeclaration, [null, null, null, { attribute: "role"; }, { optional: true; }, null, null, null, null, null, { optional: true; skipSelf: true; }, { optional: true; }]>; } // @public (undocumented)