@@ -37,7 +37,8 @@ import {Subscription} from 'rxjs/Subscription';
37
37
import { Subject } from 'rxjs/Subject' ;
38
38
import { CdkCellDef , CdkColumnDef , CdkHeaderCellDef } from './cell' ;
39
39
import {
40
- getTableDuplicateColumnNameError , getTableMissingMatchingRowDefError ,
40
+ getTableDuplicateColumnNameError ,
41
+ getTableMissingMatchingRowDefError ,
41
42
getTableMultipleDefaultRowDefsError ,
42
43
getTableUnknownColumnError
43
44
} from './table-errors' ;
@@ -68,6 +69,12 @@ export const CDK_TABLE_TEMPLATE = `
68
69
<ng-container headerRowPlaceholder></ng-container>
69
70
<ng-container rowPlaceholder></ng-container>` ;
70
71
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
+
71
78
/**
72
79
* A data table that connects with a data source to retrieve data of type `T` and renders
73
80
* 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 {
292
299
this . _changeDetectorRef . markForCheck ( ) ;
293
300
}
294
301
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
+ */
296
306
private _renderRowChanges ( ) {
297
307
const changes = this . _dataDiffer . diff ( this . _data ) ;
298
308
if ( ! changes ) { return ; }
299
309
300
310
const viewContainer = this . _rowPlaceholder . viewContainer ;
301
311
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 ) ;
305
315
} else if ( currentIndex == null ) {
306
316
viewContainer . remove ( adjustedPreviousIndex ) ;
307
317
} else {
308
- const view = viewContainer . get ( adjustedPreviousIndex ) ;
318
+ const view = < RowViewRef < T > > viewContainer . get ( adjustedPreviousIndex ) ;
309
319
viewContainer . move ( view ! , currentIndex ) ;
310
320
}
311
321
} ) ;
312
322
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
+ } ) ;
314
332
}
315
333
316
334
/**
@@ -353,14 +371,13 @@ export class CdkTable<T> implements CollectionViewer {
353
371
}
354
372
355
373
/**
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.
359
376
*/
360
- private _updateRowContext ( ) {
377
+ private _updateRowIndexContext ( ) {
361
378
const viewContainer = this . _rowPlaceholder . viewContainer ;
362
379
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 > ;
364
381
viewRef . context . index = index ;
365
382
viewRef . context . count = count ;
366
383
viewRef . context . first = index === 0 ;
@@ -404,4 +421,3 @@ export class CdkTable<T> implements CollectionViewer {
404
421
} ) ;
405
422
}
406
423
}
407
-
0 commit comments