Skip to content

Commit

Permalink
feature(data-table): support for nested objects + improved performanc…
Browse files Browse the repository at this point in the history
…e. closes(#189) (#207)

* support for nested objects + changed detection to OnPush for efficiency

* exported missing  interface ITdDataTableSelectEvent

* added refresh functon to API and README

* added example for nested objects

* workaround for angular/components#1825

* fixed tslint
  • Loading branch information
emoralesb05 authored and kyleledbetter committed Dec 26, 2016
1 parent 7db377e commit 91ab473
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 15 deletions.
23 changes: 15 additions & 8 deletions src/app/components/components/data-table/data-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ <h4 class="md-subhead">with custom headings, columns, and inline editing</h4>
<md-card>
<md-card-content>
<h3 class="md-title">Basic Data Table</h3>
<h4 class="md-subhead">with nested data, formatting, and templates</h4>
<md-divider></md-divider>
<md-tab-group md-stretch-tabs>
<md-tab>
Expand Down Expand Up @@ -137,8 +138,8 @@ <h3 class="md-title">Basic Data Table</h3>
})
export class Demo {
columns: ITdDataTableColumn[] = [
{ name: 'name', label: 'Dessert (100g serving)' },
{ name: 'type', label: 'Type' },
{ name: 'food.name', label: 'Dessert (100g serving)' },
{ name: 'food.type', label: 'Type' },
{ name: 'calories', label: 'Calories', numeric: true, format: NUMBER_FORMAT },
{ name: 'fat', label: 'Fat (g)', numeric: true, format: DECIMAL_FORMAT },
{ name: 'carbs', label: 'Carbs (g)', numeric: true, format: NUMBER_FORMAT },
Expand All @@ -151,8 +152,10 @@ <h3 class="md-title">Basic Data Table</h3>
basicData: any[] = [
{
'id': 1,
'name': 'Frozen yogurt',
'type': 'Ice cream',
'food': {
'name': 'Frozen yogurt',
'type': 'Ice cream',
},
'calories': 159.0,
'fat': 6.0,
'carbs': 24.0,
Expand All @@ -163,8 +166,10 @@ <h3 class="md-title">Basic Data Table</h3>
'comments': 'I love froyo!',
}, {
'id': 2,
'name': 'Ice cream sandwich',
'type': 'Ice cream',
'food': {
'name': 'Ice cream sandwich',
'type': 'Ice cream',
},
'calories': 237.0,
'fat': 9.0,
'carbs': 37.0,
Expand All @@ -174,8 +179,10 @@ <h3 class="md-title">Basic Data Table</h3>
'iron': 1.0,
}, {
'id': 3,
'name': 'Eclair',
'type': 'Pastry',
'food': {
'name': 'Eclair',
'type': 'Pastry',
},
'calories': 262.0,
'fat': 16.0,
'carbs': 24.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ export class DataTableDemoComponent implements OnInit {
Emits an [ITdDataTableSelectAllEvent] implemented object.`,
name: 'selectAll',
type: `function()`,
}, {
description: `Refreshes data table and updates [data] and [columns]`,
name: 'refresh',
type: `function()`,
}];

cellAttrs: Object[] = [{
Expand Down Expand Up @@ -122,7 +126,7 @@ export class DataTableDemoComponent implements OnInit {
];

data: any[] = [
{
{
'id': 1,
'name': 'Frozen yogurt',
'type': 'Ice cream',
Expand Down
1 change: 1 addition & 0 deletions src/platform/core/data-table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Properties:
| `sortChange` | `function` | Event emitted when the column headers are clicked. [sortable] needs to be enabled. Emits an [ITdDataTableSortEvent] implemented object.
| `rowSelect` | `function` | Event emitted when a row is selected/deselected. [selectable] needs to be enabled. Emits an [ITdDataTableSelectEvent] implemented object.
| `selectAll` | `function` | Event emitted when all rows are selected/deselected by the all checkbox. [selectable] needs to be enabled. Emits an [ITdDataTableSelectAllEvent] implemented object.
| `refresh` | `function` | Refreshes data table and rerenders [data] and [columns]

## Setup

Expand Down
6 changes: 4 additions & 2 deletions src/platform/core/data-table/data-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
[numeric]="column.numeric"
[active]="_sortable && column === _sortBy"
[sortable]="_sortable"
(mouseleave)="column.tooltip && tooltipRefresh()"
(mouseenter)="column.tooltip && tooltipRefresh()"
[sortOrder]="_sortOrder"
(sortChange)="handleSort(column)">
<span [md-tooltip]="column.tooltip">{{column.label}}</span>
Expand All @@ -31,11 +33,11 @@
<td td-data-table-cell
[numeric]="column.numeric"
*ngFor="let column of columns">
<span class="md-body-1" *ngIf="!getTemplateRef(column.name)">{{column.format ? column.format(row[column.name]) : row[column.name]}}</span>
<span class="md-body-1" *ngIf="!getTemplateRef(column.name)">{{column.format ? column.format(getCellValue(column, row)) : getCellValue(column, row)}}</span>
<template
*ngIf="getTemplateRef(column.name)"
[ngTemplateOutlet]="getTemplateRef(column.name)"
[ngOutletContext]="{ value: row[column.name], row: row, column: column.name }">
[ngOutletContext]="{ value: getCellValue(column, row), row: row, column: column.name }">
</template>
</td>
</tr>
Expand Down
38 changes: 35 additions & 3 deletions src/platform/core/data-table/data-table.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input, Output, EventEmitter, forwardRef,
import { Component, Input, Output, EventEmitter, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef,
ContentChildren, TemplateRef, AfterContentInit, QueryList } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

Expand Down Expand Up @@ -26,6 +26,7 @@ export interface ITdDataTableColumn {
tooltip?: string;
numeric?: boolean;
format?: (value: any) => any;
nested?: boolean;
};

export interface ITdDataTableSelectEvent {
Expand All @@ -43,6 +44,7 @@ export interface ITdDataTableSelectAllEvent {
selector: 'td-data-table',
styleUrls: [ 'data-table.component.scss' ],
templateUrl: 'data-table.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TdDataTableComponent implements ControlValueAccessor, AfterContentInit {

Expand Down Expand Up @@ -214,6 +216,8 @@ export class TdDataTableComponent implements ControlValueAccessor, AfterContentI
@Output('selectAll') onSelectAll: EventEmitter<ITdDataTableSelectAllEvent> =
new EventEmitter<ITdDataTableSelectAllEvent>();

constructor(private _changeDetectorRef: ChangeDetectorRef) {}

/**
* Loads templates and sets them in a map for faster access.
*/
Expand All @@ -224,7 +228,14 @@ export class TdDataTableComponent implements ControlValueAccessor, AfterContentI
this._templates.toArray()[i].templateRef
);
}
}
}

getCellValue(column: ITdDataTableColumn, value: any): string {
if (column.nested === undefined || column.nested) {
return this._getNestedValue(column.name, value);
}
return value[column.name];
}

/**
* Getter method for template references
Expand All @@ -244,7 +255,16 @@ export class TdDataTableComponent implements ControlValueAccessor, AfterContentI
* Refreshes data table and rerenders [data] and [columns]
*/
refresh(): void {
this.clearModel();
this._changeDetectorRef.markForCheck();
}

/**
* Workaround for https://github.com/angular/material2/issues/1825
*/
tooltipRefresh(): void {
setTimeout(() => {
this.refresh();
}, 100);
}

/**
Expand Down Expand Up @@ -346,4 +366,16 @@ export class TdDataTableComponent implements ControlValueAccessor, AfterContentI
onChange = (_: any) => noop;
onTouched = () => noop;

private _getNestedValue(name: string, value: any): string {
if (!(value instanceof Object) || !name) {
return value;
}
if (name.indexOf('.') > -1) {
let splitName: string[] = name.split(/\.(.+)/, 2);
return this._getNestedValue(splitName[1], value[splitName[0]]);
} else {
return value[name];
}
}

}
2 changes: 1 addition & 1 deletion src/platform/core/data-table/data-table.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const TD_DATA_TABLE: Type<any>[] = [
];

export { TdDataTableComponent, TdDataTableSortingOrder,
ITdDataTableColumn } from './data-table.component';
ITdDataTableColumn, ITdDataTableSelectEvent } from './data-table.component';
export { TdDataTableService } from './services/data-table.service';
export { TdDataTableColumnComponent,
ITdDataTableSortChangeEvent } from './data-table-column/data-table-column.component';
Expand Down

0 comments on commit 91ab473

Please sign in to comment.