1+ import { Observable } from 'rxjs/Observable' ;
2+ import { BehaviorSubject } from 'rxjs/Rx' ;
3+ import { MdTableSortOrder , MdTableDataSource , MdTableRows } from '@angular/material' ;
4+
5+ export interface Character {
6+ name : string ;
7+ movie : string ;
8+ villan ?: boolean ;
9+ }
10+
11+ export const CHARACTERS = [
12+ { name : 'Goofy' , movie : 'A Goofy Movie' } ,
13+ { name : 'Tinker Bell' , movie : 'Peter Pan' } ,
14+ { name : 'Thumper' , movie : 'Bambi' } ,
15+ { name : 'Mad Hatter' , movie : 'Alice in Wonderland' } ,
16+ { name : 'Kronk' , movie : 'The Emperor\'s New Groove' , villan : true } ,
17+ { name : 'Gus Gus' , movie : 'Cinderella' } ,
18+ { name : 'Jiminy Cricket' , movie : 'Pinocchio' } ,
19+ { name : 'Tigger' , movie : 'Winnie the Pooh' } ,
20+ { name : 'Gaston' , movie : 'Beauty and the Beast' , villan : true } ,
21+ { name : 'Dumbo' , movie : 'Dumbo' } ,
22+ { name : 'Jafar' , movie : 'Aladdin' , villan : true } ,
23+ { name : 'Lilo' , movie : 'Lilo and Stitch' } ,
24+ { name : 'Sebastian' , movie : 'The Little Mermaid' } ,
25+ { name : 'Jane' , movie : 'Tarzan' } ,
26+ { name : 'Pumbaa' , movie : 'The Lion King' } ,
27+ { name : 'Mulan' , movie : 'Mulan' } ,
28+ ] ;
29+
30+ export class TableDemoDataSource implements MdTableDataSource < Character > {
31+ private readonly rowSubject =
32+ new BehaviorSubject < MdTableRows < Character > > ( { rows : [ ] , rowCount : 0 } ) ;
33+
34+ filter : string ;
35+ sortOrder : MdTableSortOrder ;
36+ sortColumn : string ;
37+
38+ constructor ( ) {
39+ this . loadTableRows ( ) ;
40+ }
41+
42+ /**
43+ * Returns an observable the table watches in order to update rows.
44+ * @override
45+ */
46+ getRows ( ) : Observable < MdTableRows < Character > > {
47+ return this . rowSubject . asObservable ( ) ;
48+ }
49+
50+ /**
51+ * Updates the table based on the table settings and filters.
52+ */
53+ loadTableRows ( ) {
54+ this . getRowsFromServer ( ) . subscribe ( filteredRows => {
55+ const rows = { rows : filteredRows , rowCount : filteredRows . length } ;
56+ this . rowSubject . next ( rows ) ;
57+ } ) ;
58+ }
59+
60+ /**
61+ * Simulates getting a list of filtered rows from the server with a delay.
62+ */
63+ getRowsFromServer ( ) : Observable < Character [ ] > {
64+ const filteredRows = CHARACTERS . filter ( this . matchesSearchTerm . bind ( this ) ) ;
65+ if ( this . sortColumn ) {
66+ filteredRows . sort ( this . compareRows . bind ( this ) ) ;
67+ if ( this . sortOrder === 'descending' ) {
68+ filteredRows . reverse ( ) ;
69+ }
70+ }
71+
72+ return Observable . of ( filteredRows ) ;
73+ }
74+
75+ private matchesSearchTerm ( row : Character ) : boolean {
76+ if ( ! this . filter ) {
77+ return true ; // Everything matches.
78+ }
79+
80+ return ( row . name + row . movie ) . toLowerCase ( ) . indexOf ( this . filter . toLowerCase ( ) ) != - 1 ;
81+ }
82+
83+ private compareRows ( a : Character , b : Character ) : number {
84+ if ( ! this . sortColumn ) { return 0 ; }
85+
86+ let valueA : string ;
87+ let valueB : string ;
88+ if ( this . sortColumn == 'name' ) {
89+ valueA = a . name ;
90+ valueB = b . name ;
91+ } else if ( this . sortColumn == 'movie' ) {
92+ valueA = a . movie ;
93+ valueB = b . movie ;
94+ }
95+
96+ // For arbitrary objects, if the valueOf method is overridden, then
97+ // comparison will use that. Otherwise, sorting will do nothing.
98+ if ( valueA < valueB ) {
99+ return - 1 ;
100+ } else if ( valueA > valueB ) {
101+ return 1 ;
102+ } else {
103+ return 0 ;
104+ }
105+ }
106+ }
0 commit comments