From 5379c173d3d0df876068eed15ad5fd08af64ec17 Mon Sep 17 00:00:00 2001 From: Andrew Seguin Date: Tue, 12 Mar 2019 10:54:11 -0700 Subject: [PATCH] fix(table): use default change detection strategy on table This resolves an issue with Ivy where change detection was not reflecting binding changes made to the row and cell templates in the component declaring the table. In View Engine, change detection for a dynamically created view runs in two cases: 1) When the view in which it was inserted is checked 2) When the view in which it was declared is checked As a result, if a dynamic view is inserted into an OnPush component, that view is not actually checked only "on push". It is also checked as often as its declaration view is checked (even if the insertion view is explicitly detached from change detection). For this reason, marking `MatTable` as "OnPush" doesn't have much of an effect. It is built almost entirely of views that are declared elsewhere, so its change detection frequency is dependent on those declaration views. It also doesn't have any bindings inside its own view that would be protected by "OnPush", so marking it this way is effectively a noop and can be removed without performance regressions. In Ivy, this change detection loophole has been closed, so declaration views can no longer de-optimize OnPush components. This means bindings inherited from declaration views aren't updated by default if `MatTable` is OnPush (the embedded view would need to be marked dirty explicitly). To avoid breaking changes when we transition to Ivy, it makes more sense to perpetuate the current behavior by removing the "OnPush" marker. As delineated earlier, this has no impact on View Engine. For Ivy, it would ensure bindings inherited from the declaration view are still checked by default. --- src/cdk/table/row.ts | 39 ++++--- src/cdk/table/table.ts | 153 ++++++++++++++------------ src/lib/table/row.ts | 43 +++++--- src/lib/table/table.ts | 4 +- tools/public_api_guard/cdk/table.d.ts | 5 +- 5 files changed, 138 insertions(+), 106 deletions(-) diff --git a/src/cdk/table/row.ts b/src/cdk/table/row.ts index 31e7379cb9d4..067e294edfe7 100644 --- a/src/cdk/table/row.ts +++ b/src/cdk/table/row.ts @@ -18,7 +18,7 @@ import { SimpleChanges, TemplateRef, ViewContainerRef, - ViewEncapsulation, + ViewEncapsulation } from '@angular/core'; import {CanStick, CanStickCtor, mixinHasStickyInput} from './can-stick'; import {CdkCellDef, CdkColumnDef} from './cell'; @@ -40,8 +40,9 @@ export abstract class BaseRowDef implements OnChanges { /** Differ used to check if any changes were made to the columns. */ protected _columnsDiffer: IterableDiffer; - constructor(/** @docs-private */ public template: TemplateRef, - protected _differs: IterableDiffers) { } + constructor( + /** @docs-private */ public template: TemplateRef, protected _differs: IterableDiffers) { + } ngOnChanges(changes: SimpleChanges): void { // Create a new columns differ if one does not yet exist. Initialize it based on initial value @@ -57,7 +58,7 @@ export abstract class BaseRowDef implements OnChanges { * Returns the difference between the current columns and the columns from the last diff, or null * if there is no difference. */ - getColumnsDiff(): IterableChanges | null { + getColumnsDiff(): IterableChanges|null { return this._columnsDiffer.diff(this.columns); } @@ -65,7 +66,8 @@ export abstract class BaseRowDef implements OnChanges { extractCellTemplate(column: CdkColumnDef): TemplateRef { if (this instanceof CdkHeaderRowDef) { return column.headerCell.template; - } if (this instanceof CdkFooterRowDef) { + } + if (this instanceof CdkFooterRowDef) { return column.footerCell.template; } else { return column.cell.template; @@ -76,7 +78,7 @@ export abstract class BaseRowDef implements OnChanges { // Boilerplate for applying mixins to CdkHeaderRowDef. /** @docs-private */ export class CdkHeaderRowDefBase extends BaseRowDef {} -export const _CdkHeaderRowDefBase: CanStickCtor & typeof CdkHeaderRowDefBase = +export const _CdkHeaderRowDefBase: CanStickCtor&typeof CdkHeaderRowDefBase = mixinHasStickyInput(CdkHeaderRowDefBase); /** @@ -102,7 +104,7 @@ export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, O // Boilerplate for applying mixins to CdkFooterRowDef. /** @docs-private */ export class CdkFooterRowDefBase extends BaseRowDef {} -export const _CdkFooterRowDefBase: CanStickCtor & typeof CdkFooterRowDefBase = +export const _CdkFooterRowDefBase: CanStickCtor&typeof CdkFooterRowDefBase = mixinHasStickyInput(CdkFooterRowDefBase); /** @@ -224,7 +226,7 @@ export class CdkCellOutlet implements OnDestroy { * a handle to provide that component's cells and context. After init, the CdkCellOutlet will * construct the cells with the provided context. */ - static mostRecentCellOutlet: CdkCellOutlet | null = null; + static mostRecentCellOutlet: CdkCellOutlet|null = null; constructor(public _viewContainer: ViewContainerRef) { CdkCellOutlet.mostRecentCellOutlet = this; @@ -248,10 +250,13 @@ export class CdkCellOutlet implements OnDestroy { 'class': 'cdk-header-row', 'role': 'row', }, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, }) -export class CdkHeaderRow { } +export class CdkHeaderRow { +} /** Footer template container that contains the cell outlet. Adds the right class and role. */ @@ -263,10 +268,13 @@ export class CdkHeaderRow { } 'class': 'cdk-footer-row', 'role': 'row', }, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, }) -export class CdkFooterRow { } +export class CdkFooterRow { +} /** Data row template container that contains the cell outlet. Adds the right class and role. */ @Component({ @@ -277,7 +285,10 @@ export class CdkFooterRow { } 'class': 'cdk-row', 'role': 'row', }, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, }) -export class CdkRow { } +export class CdkRow { +} diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts index 50cabf656b35..35b21e0c7cdb 100644 --- a/src/cdk/table/table.ts +++ b/src/cdk/table/table.ts @@ -6,7 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ +import {Direction, Directionality} from '@angular/cdk/bidi'; +import {coerceBooleanProperty} from '@angular/cdk/coercion'; import {CollectionViewer, DataSource, isDataSource} from '@angular/cdk/collections'; +import {Platform} from '@angular/cdk/platform'; +import {DOCUMENT} from '@angular/common'; import { AfterContentChecked, Attribute, @@ -17,6 +21,7 @@ import { Directive, ElementRef, EmbeddedViewRef, + Inject, Input, isDevMode, IterableChangeRecord, @@ -30,10 +35,8 @@ import { TrackByFunction, ViewChild, ViewContainerRef, - ViewEncapsulation, - Inject, + ViewEncapsulation } from '@angular/core'; -import {DOCUMENT} from '@angular/common'; import {BehaviorSubject, Observable, of as observableOf, Subject, Subscription} from 'rxjs'; import {takeUntil} from 'rxjs/operators'; import {CdkColumnDef} from './cell'; @@ -46,6 +49,7 @@ import { CdkHeaderRowDef, CdkRowDef } from './row'; +import {StickyStyler} from './sticky-styler'; import { getTableDuplicateColumnNameError, getTableMissingMatchingRowDefError, @@ -54,10 +58,6 @@ import { getTableUnknownColumnError, getTableUnknownDataSourceError } from './table-errors'; -import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {StickyStyler} from './sticky-styler'; -import {Direction, Directionality} from '@angular/cdk/bidi'; -import {Platform} from '@angular/cdk/platform'; /** Interface used to provide an outlet for rows to be inserted into. */ export interface RowOutlet { @@ -68,8 +68,8 @@ export interface RowOutlet { * Union of the types that can be set as the data source for a `CdkTable`. * @docs-private */ -type CdkTableDataSourceInput = DataSource | Observable | T[]> | - ReadonlyArray | T[]; +type CdkTableDataSourceInput = + DataSource|Observable|T[]>|ReadonlyArray|T[]; /** * Provides a handle for the table to grab the view container's ng-container to insert data rows. @@ -77,8 +77,7 @@ type CdkTableDataSourceInput = DataSource | Observable | */ @Directive({selector: '[rowOutlet]'}) export class DataRowOutlet implements RowOutlet { - constructor(public viewContainer: ViewContainerRef, - public elementRef: ElementRef) { } + constructor(public viewContainer: ViewContainerRef, public elementRef: ElementRef) {} } /** @@ -87,8 +86,7 @@ export class DataRowOutlet implements RowOutlet { */ @Directive({selector: '[headerRowOutlet]'}) export class HeaderRowOutlet implements RowOutlet { - constructor(public viewContainer: ViewContainerRef, - public elementRef: ElementRef) { } + constructor(public viewContainer: ViewContainerRef, public elementRef: ElementRef) {} } /** @@ -97,8 +95,7 @@ export class HeaderRowOutlet implements RowOutlet { */ @Directive({selector: '[footerRowOutlet]'}) export class FooterRowOutlet implements RowOutlet { - constructor(public viewContainer: ViewContainerRef, - public elementRef: ElementRef) { } + constructor(public viewContainer: ViewContainerRef, public elementRef: ElementRef) {} } /** @@ -107,9 +104,9 @@ export class FooterRowOutlet implements RowOutlet { * @docs-private */ export const CDK_TABLE_TEMPLATE = -// Note that according to MDN, the `caption` element has to be projected as the **first** element -// in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption -` + // Note that according to MDN, the `caption` element has to be projected as the **first** + // element in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption + ` @@ -120,14 +117,14 @@ export const CDK_TABLE_TEMPLATE = * Interface used to conveniently type the possible context interfaces for the render row. * @docs-private */ -export interface RowContext - extends CdkCellOutletMultiRowContext, CdkCellOutletRowContext { } +export interface RowContext extends CdkCellOutletMultiRowContext, + CdkCellOutletRowContext {} /** * Class used to conveniently type the embedded view ref for rows with a context. * @docs-private */ -abstract class RowViewRef extends EmbeddedViewRef> { } +abstract class RowViewRef extends EmbeddedViewRef> {} /** * Set of properties that represents the identity of a single rendered row. @@ -163,13 +160,17 @@ export interface RenderRow { 'class': 'cdk-table', }, encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, + // The "OnPush" status for the `MatTable` component is effectively a noop, so we are removing it. + // The view for `MatTable` consists entirely of templates declared in other views. As they are + // declared elsewhere, they are checked when their declaration points are checked. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, }) export class CdkTable implements AfterContentChecked, CollectionViewer, OnDestroy, OnInit { private _document: Document; /** Latest data provided by the data source. */ - protected _data: T[] | ReadonlyArray; + protected _data: T[]|ReadonlyArray; /** Subject that emits when the component has been destroyed. */ private _onDestroy = new Subject(); @@ -178,14 +179,14 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes private _renderRows: RenderRow[]; /** Subscription that listens for the data provided by the data source. */ - private _renderChangeSubscription: Subscription | null; + private _renderChangeSubscription: Subscription|null; /** * Map of all the user's defined columns (header, data, and footer cell template) identified by * name. Collection populated by the column definitions gathered by `ContentChildren` as well as * any custom column definitions added to `_customColumnDefs`. */ - private _columnDefsByName = new Map(); + private _columnDefsByName = new Map(); /** * Set of all row definitions that can be used by this table. Populated by the rows gathered by @@ -211,7 +212,7 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes private _dataDiffer: IterableDiffer>; /** Stores the row definition that does not have a when predicate. */ - private _defaultRowDef: CdkRowDef | null; + private _defaultRowDef: CdkRowDef|null; /** * Column definitions that were defined outside of the direct content children of the table. @@ -290,12 +291,13 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes * Accepts a function that takes two parameters, `index` and `item`. */ @Input() - get trackBy(): TrackByFunction { return this._trackByFn; } + get trackBy(): TrackByFunction { + return this._trackByFn; + } set trackBy(fn: TrackByFunction) { - if (isDevMode() && - fn != null && typeof fn !== 'function' && - console && console.warn) { - console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}.`); + if (isDevMode() && fn != null && typeof fn !== 'function' && console && + console.warn) { + console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}.`); } this._trackByFn = fn; } @@ -322,7 +324,9 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes * subscriptions registered during the connect process). */ @Input() - get dataSource(): CdkTableDataSourceInput { return this._dataSource; } + get dataSource(): CdkTableDataSourceInput { + return this._dataSource; + } set dataSource(dataSource: CdkTableDataSourceInput) { if (this._dataSource !== dataSource) { this._switchDataSource(dataSource); @@ -337,7 +341,9 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes * defined in the table, or otherwise the default row which does not have a when predicate. */ @Input() - get multiTemplateDataRows(): boolean { return this._multiTemplateDataRows; } + get multiTemplateDataRows(): boolean { + return this._multiTemplateDataRows; + } set multiTemplateDataRows(v: boolean) { this._multiTemplateDataRows = coerceBooleanProperty(v); if (this._rowOutlet.viewContainer.length) { @@ -375,18 +381,17 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes /** Set of footer row definitions that were provided to the table as content children. */ @ContentChildren(CdkFooterRowDef) _contentFooterRowDefs: QueryList; - constructor(protected readonly _differs: IterableDiffers, - protected readonly _changeDetectorRef: ChangeDetectorRef, - protected readonly _elementRef: ElementRef, - @Attribute('role') role: string, - @Optional() protected readonly _dir: Directionality, - /** - * @deprecated - * @breaking-change 8.0.0 `_document` and `_platform` to - * be made into a required parameters. - */ - @Inject(DOCUMENT) _document?: any, - private _platform?: Platform) { + constructor( + protected readonly _differs: IterableDiffers, + protected readonly _changeDetectorRef: ChangeDetectorRef, + protected readonly _elementRef: ElementRef, @Attribute('role') role: string, + @Optional() protected readonly _dir: Directionality, + /** + * @deprecated + * @breaking-change 8.0.0 `_document` and `_platform` to + * be made into a required parameters. + */ + @Inject(DOCUMENT) _document?: any, private _platform?: Platform) { if (!role) { this._elementRef.nativeElement.setAttribute('role', 'grid'); } @@ -472,22 +477,24 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes renderRows() { this._renderRows = this._getAllRenderRows(); const changes = this._dataDiffer.diff(this._renderRows); - if (!changes) { return; } + if (!changes) { + return; + } const viewContainer = this._rowOutlet.viewContainer; - changes.forEachOperation((record: IterableChangeRecord>, - prevIndex: number | null, - currentIndex: number | null) => { - if (record.previousIndex == null) { - this._insertRow(record.item, currentIndex!); - } else if (currentIndex == null) { - viewContainer.remove(prevIndex!); - } else { - const view = >viewContainer.get(prevIndex!); - viewContainer.move(view!, currentIndex); - } - }); + changes.forEachOperation( + (record: IterableChangeRecord>, prevIndex: number|null, + currentIndex: number|null) => { + if (record.previousIndex == null) { + this._insertRow(record.item, currentIndex!); + } else if (currentIndex == null) { + viewContainer.remove(prevIndex!); + } else { + const view = >viewContainer.get(prevIndex!); + viewContainer.move(view!, currentIndex); + } + }); // Update the meta context of a row's context data (index, count, first, last, ...) this._updateRowIndexContext(); @@ -750,8 +757,7 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes mergeQueryListAndSet(this._contentHeaderRowDefs, this._customHeaderRowDefs); this._footerRowDefs = mergeQueryListAndSet(this._contentFooterRowDefs, this._customFooterRowDefs); - this._rowDefs = - mergeQueryListAndSet(this._contentRowDefs, this._customRowDefs); + this._rowDefs = mergeQueryListAndSet(this._contentRowDefs, this._customRowDefs); // After all row definitions are determined, find the row definition to be considered default. const defaultRowDefs = this._rowDefs.filter(def => !def.when); @@ -815,9 +821,11 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes /** Set up a subscription for the data provided by the data source. */ private _observeRenderChanges() { // If no data source has been set, there is nothing to observe for changes. - if (!this.dataSource) { return; } + if (!this.dataSource) { + return; + } - let dataStream: Observable> | undefined; + let dataStream: Observable>|undefined; if (isDataSource(this.dataSource)) { dataStream = this.dataSource.connect(this); @@ -831,12 +839,10 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes throw getTableUnknownDataSourceError(); } - this._renderChangeSubscription = dataStream - .pipe(takeUntil(this._onDestroy)) - .subscribe(data => { - this._data = data || []; - this.renderRows(); - }); + this._renderChangeSubscription = dataStream.pipe(takeUntil(this._onDestroy)).subscribe(data => { + this._data = data || []; + this.renderRows(); + }); } /** @@ -901,7 +907,9 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes * definition. */ _getRowDefs(data: T, dataIndex: number): CdkRowDef[] { - if (this._rowDefs.length == 1) { return [this._rowDefs[0]]; } + if (this._rowDefs.length == 1) { + return [this._rowDefs[0]]; + } let rowDefs: CdkRowDef[] = []; if (this.multiTemplateDataRows) { @@ -976,7 +984,9 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes /** Gets the column definitions for the provided row def. */ private _getCellTemplates(rowDef: BaseRowDef): TemplateRef[] { - if (!rowDef || !rowDef.columns) { return []; } + if (!rowDef || !rowDef.columns) { + return []; + } return Array.from(rowDef.columns, columnId => { const column = this._columnDefsByName.get(columnId); @@ -1056,7 +1066,8 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes */ private _setupStickyStyler() { const direction: Direction = this._dir ? this._dir.value : 'ltr'; - this._stickyStyler = new StickyStyler(this._isNativeHtmlTable, + this._stickyStyler = new StickyStyler( + this._isNativeHtmlTable, // @breaking-change 8.0.0 remove the null check for `this._platform`. this.stickyCssClass, direction, this._platform ? this._platform.isBrowser : true); (this._dir ? this._dir.change : observableOf()) diff --git a/src/lib/table/row.ts b/src/lib/table/row.ts index 2c1f3f0b320a..000a786f9531 100644 --- a/src/lib/table/row.ts +++ b/src/lib/table/row.ts @@ -7,18 +7,15 @@ */ import { - ChangeDetectionStrategy, - Component, - Directive, - ViewEncapsulation -} from '@angular/core'; -import { - CDK_ROW_TEMPLATE, CdkFooterRow, CdkFooterRowDef, + CDK_ROW_TEMPLATE, + CdkFooterRow, + CdkFooterRowDef, CdkHeaderRow, CdkHeaderRowDef, CdkRow, - CdkRowDef, + CdkRowDef } from '@angular/cdk/table'; +import {ChangeDetectionStrategy, Component, Directive, ViewEncapsulation} from '@angular/core'; /** * Header row definition for the mat-table. @@ -29,7 +26,8 @@ import { providers: [{provide: CdkHeaderRowDef, useExisting: MatHeaderRowDef}], inputs: ['columns: matHeaderRowDef', 'sticky: matHeaderRowDefSticky'], }) -export class MatHeaderRowDef extends CdkHeaderRowDef {} +export class MatHeaderRowDef extends CdkHeaderRowDef { +} /** * Footer row definition for the mat-table. @@ -40,7 +38,8 @@ export class MatHeaderRowDef extends CdkHeaderRowDef {} providers: [{provide: CdkFooterRowDef, useExisting: MatFooterRowDef}], inputs: ['columns: matFooterRowDef', 'sticky: matFooterRowDefSticky'], }) -export class MatFooterRowDef extends CdkFooterRowDef {} +export class MatFooterRowDef extends CdkFooterRowDef { +} /** * Data row definition for the mat-table. @@ -52,7 +51,8 @@ export class MatFooterRowDef extends CdkFooterRowDef {} providers: [{provide: CdkRowDef, useExisting: MatRowDef}], inputs: ['columns: matRowDefColumns', 'when: matRowDefWhen'], }) -export class MatRowDef extends CdkRowDef {} +export class MatRowDef extends CdkRowDef { +} /** Footer template container that contains the cell outlet. Adds the right class and role. */ @Component({ @@ -63,12 +63,15 @@ export class MatRowDef extends CdkRowDef {} 'class': 'mat-header-row', 'role': 'row', }, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, exportAs: 'matHeaderRow', providers: [{provide: CdkHeaderRow, useExisting: MatHeaderRow}], }) -export class MatHeaderRow extends CdkHeaderRow { } +export class MatHeaderRow extends CdkHeaderRow { +} /** Footer template container that contains the cell outlet. Adds the right class and role. */ @Component({ @@ -79,12 +82,15 @@ export class MatHeaderRow extends CdkHeaderRow { } 'class': 'mat-footer-row', 'role': 'row', }, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, exportAs: 'matFooterRow', providers: [{provide: CdkFooterRow, useExisting: MatFooterRow}], }) -export class MatFooterRow extends CdkFooterRow { } +export class MatFooterRow extends CdkFooterRow { +} /** Data row template container that contains the cell outlet. Adds the right class and role. */ @Component({ @@ -95,9 +101,12 @@ export class MatFooterRow extends CdkFooterRow { } 'class': 'mat-row', 'role': 'row', }, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, exportAs: 'matRow', providers: [{provide: CdkRow, useExisting: MatRow}], }) -export class MatRow extends CdkRow { } +export class MatRow extends CdkRow { +} diff --git a/src/lib/table/table.ts b/src/lib/table/table.ts index d6acb8649934..8aa93eede9f3 100644 --- a/src/lib/table/table.ts +++ b/src/lib/table/table.ts @@ -22,7 +22,9 @@ import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/co 'class': 'mat-table', }, encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, + // See note on CdkTable for explanation on why this uses the default change detection strategy. + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, }) export class MatTable extends CdkTable { /** Overrides the sticky CSS class set by the `CdkTable`. */ diff --git a/tools/public_api_guard/cdk/table.d.ts b/tools/public_api_guard/cdk/table.d.ts index cb14dade32c1..d2e7e699e1b1 100644 --- a/tools/public_api_guard/cdk/table.d.ts +++ b/tools/public_api_guard/cdk/table.d.ts @@ -11,9 +11,8 @@ export declare class BaseCdkCell { export declare abstract class BaseRowDef implements OnChanges { protected _columnsDiffer: IterableDiffer; protected _differs: IterableDiffers; - columns: Iterable; - template: TemplateRef; - constructor(/** @docs-private */ template: TemplateRef, _differs: IterableDiffers); + columns: Iterable; template: TemplateRef; + constructor( template: TemplateRef, _differs: IterableDiffers); extractCellTemplate(column: CdkColumnDef): TemplateRef; getColumnsDiff(): IterableChanges | null; ngOnChanges(changes: SimpleChanges): void;