@@ -37,7 +37,8 @@ import {Subscription} from 'rxjs/Subscription';
3737import { Subject } from 'rxjs/Subject' ;
3838import { CdkCellDef , CdkColumnDef , CdkHeaderCellDef } from './cell' ;
3939import {
40- getTableDuplicateColumnNameError , getTableMissingMatchingRowDefError ,
40+ getTableDuplicateColumnNameError ,
41+ getTableMissingMatchingRowDefError ,
4142 getTableMultipleDefaultRowDefsError ,
4243 getTableUnknownColumnError
4344} from './table-errors' ;
@@ -68,6 +69,12 @@ export const CDK_TABLE_TEMPLATE = `
6869 <ng-container headerRowPlaceholder></ng-container>
6970 <ng-container rowPlaceholder></ng-container>` ;
7071
72+ /**
73+ * Class used to conveniently type the embedded view ref for rows with a context.
74+ * @docs -private
75+ */
76+ abstract class RowViewRef < T > extends EmbeddedViewRef < CdkCellOutletRowContext < T > > { }
77+
7178/**
7279 * A data table that connects with a data source to retrieve data of type `T` and renders
7380 * a header row and data rows. Updates the rows when new data is provided by the data source.
@@ -292,25 +299,36 @@ export class CdkTable<T> implements CollectionViewer {
292299 this . _changeDetectorRef . markForCheck ( ) ;
293300 }
294301
295- /** Check for changes made in the data and render each change (row added/removed/moved). */
302+ /**
303+ * Check for changes made in the data and render each change (row added/removed/moved) and update
304+ * row contexts.
305+ */
296306 private _renderRowChanges ( ) {
297307 const changes = this . _dataDiffer . diff ( this . _data ) ;
298308 if ( ! changes ) { return ; }
299309
300310 const viewContainer = this . _rowPlaceholder . viewContainer ;
301311 changes . forEachOperation (
302- ( item : IterableChangeRecord < any > , adjustedPreviousIndex : number , currentIndex : number ) => {
303- if ( item . previousIndex == null ) {
304- this . _insertRow ( this . _data [ currentIndex ] , currentIndex ) ;
312+ ( record : IterableChangeRecord < T > , adjustedPreviousIndex : number , currentIndex : number ) => {
313+ if ( record . previousIndex == null ) {
314+ this . _insertRow ( record . item , currentIndex ) ;
305315 } else if ( currentIndex == null ) {
306316 viewContainer . remove ( adjustedPreviousIndex ) ;
307317 } else {
308- const view = viewContainer . get ( adjustedPreviousIndex ) ;
318+ const view = < RowViewRef < T > > viewContainer . get ( adjustedPreviousIndex ) ;
309319 viewContainer . move ( view ! , currentIndex ) ;
310320 }
311321 } ) ;
312322
313- this . _updateRowContext ( ) ;
323+ // Update the meta context of a row's context data (index, count, first, last, ...)
324+ this . _updateRowIndexContext ( ) ;
325+
326+ // Update rows that did not get added/removed/moved but may have had their identity changed,
327+ // e.g. if trackBy matched data on some property but the actual data reference changed.
328+ changes . forEachIdentityChange ( ( record : IterableChangeRecord < T > ) => {
329+ const rowView = < RowViewRef < T > > viewContainer . get ( record . currentIndex ! ) ;
330+ rowView . context . $implicit = record . item ;
331+ } ) ;
314332 }
315333
316334 /**
@@ -353,14 +371,13 @@ export class CdkTable<T> implements CollectionViewer {
353371 }
354372
355373 /**
356- * Updates the context for each row to reflect any data changes that may have caused
357- * rows to be added, removed, or moved. The view container contains the same context
358- * that was provided to each of its cells.
374+ * Updates the index-related context for each row to reflect any changes in the index of the rows,
375+ * e.g. first/last/even/odd.
359376 */
360- private _updateRowContext ( ) {
377+ private _updateRowIndexContext ( ) {
361378 const viewContainer = this . _rowPlaceholder . viewContainer ;
362379 for ( let index = 0 , count = viewContainer . length ; index < count ; index ++ ) {
363- const viewRef = viewContainer . get ( index ) as EmbeddedViewRef < CdkCellOutletRowContext < T > > ;
380+ const viewRef = viewContainer . get ( index ) as RowViewRef < T > ;
364381 viewRef . context . index = index ;
365382 viewRef . context . count = count ;
366383 viewRef . context . first = index === 0 ;
@@ -404,4 +421,3 @@ export class CdkTable<T> implements CollectionViewer {
404421 } ) ;
405422 }
406423}
407-
0 commit comments