Last active
July 6, 2022 11:22
-
-
Save jhades/9cdcff38c5f5092069363ddf69bda5bf to your computer and use it in GitHub Desktop.
Angular Material Data Table blog post - https://blog.angular-university.io/angular-material-data-table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { MatInputModule, MatPaginatorModule, MatProgressSpinnerModule, | |
| MatSortModule, MatTableModule } from "@angular/material"; | |
| @NgModule({ | |
| declarations: [ | |
| ... | |
| ], | |
| imports: [ | |
| BrowserModule, | |
| BrowserAnimationsModule, | |
| HttpClientModule, | |
| MatInputModule, | |
| MatTableModule, | |
| MatPaginatorModule, | |
| MatSortModule, | |
| MatProgressSpinnerModule | |
| ], | |
| providers: [ | |
| ... | |
| ], | |
| bootstrap: [AppComponent] | |
| }) | |
| export class AppModule { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"> | |
| <ng-container matColumnDef="seqNo"> | |
| <div *matHeaderCellDef>#</div> | |
| <div *matCellDef="let lesson">{{lesson.seqNo}}</div> | |
| </ng-container> | |
| <ng-container matColumnDef="description"> | |
| <div *matHeaderCellDef>Description</div> | |
| <div class="description-cell" | |
| *matCellDef="let lesson">{{lesson.description}}</div> | |
| </ng-container> | |
| <ng-container matColumnDef="duration"> | |
| <div *matHeaderCellDef>Duration</div> | |
| <div class="duration-cell" | |
| *matCellDef="let lesson">{{lesson.duration}}</div> | |
| </ng-container> | |
| <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> | |
| <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row> | |
| </mat-table> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"> | |
| <ng-container matColumnDef="seqNo"> | |
| <mat-header-cell *matHeaderCellDef>#</mat-header-cell> | |
| <mat-cell *matCellDef="let lesson">{{lesson.seqNo}}</mat-cell> | |
| </ng-container> | |
| <ng-container matColumnDef="description"> | |
| <mat-header-cell *matHeaderCellDef>Description</mat-header-cell> | |
| <mat-cell class="description-cell" | |
| *matCellDef="let lesson">{{lesson.description}}</mat-cell> | |
| </ng-container> | |
| <ng-container matColumnDef="duration"> | |
| <mat-header-cell *matHeaderCellDef>Duration</mat-header-cell> | |
| <mat-cell class="duration-cell" | |
| *matCellDef="let lesson">{{lesson.duration}}</mat-cell> | |
| </ng-container> | |
| <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> | |
| <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row> | |
| </mat-table> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| displayedColumns = ["seqNo", "description", "duration"]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <mat-row *matRowDef="let row; columns: displayedColumns" | |
| (click)="onRowClicked(row)"> | |
| </mat-row> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| onRowClicked(row) { | |
| console.log('Row clicked: ', row); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Injectable() | |
| export class CoursesService { | |
| constructor(private http:HttpClient) {} | |
| findLessons( | |
| courseId:number, filter = '', sortOrder = 'asc', | |
| pageNumber = 0, pageSize = 3): Observable<Lesson[]> { | |
| return this.http.get('/api/lessons', { | |
| params: new HttpParams() | |
| .set('courseId', courseId.toString()) | |
| .set('filter', filter) | |
| .set('sortOrder', sortOrder) | |
| .set('pageNumber', pageNumber.toString()) | |
| .set('pageSize', pageSize.toString()) | |
| }).pipe( | |
| map(res => res["payload"]) | |
| ); | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {CollectionViewer, DataSource} from "@angular/cdk/collections"; | |
| export class LessonsDataSource implements DataSource<Lesson> { | |
| private lessonsSubject = new BehaviorSubject<Lesson[]>([]); | |
| constructor(private coursesService: CoursesService) {} | |
| connect(collectionViewer: CollectionViewer): Observable<Lesson[]> { | |
| ... | |
| } | |
| disconnect(collectionViewer: CollectionViewer): void { | |
| ... | |
| } | |
| loadLessons(courseId: number, filter: string, | |
| sortDirection: string, pageIndex: number, pageSize: number) { | |
| ... | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export class LessonsDataSource implements DataSource<Lesson> { | |
| private lessonsSubject = new BehaviorSubject<Lesson[]>([]); | |
| private loadingSubject = new BehaviorSubject<boolean>(false); | |
| public loading$ = this.loadingSubject.asObservable(); | |
| constructor(private coursesService: CoursesService) {} | |
| connect(collectionViewer: CollectionViewer): Observable<Lesson[]> { | |
| return this.lessonsSubject.asObservable(); | |
| } | |
| disconnect(collectionViewer: CollectionViewer): void { | |
| this.lessonsSubject.complete(); | |
| this.loadingSubject.complete(); | |
| } | |
| loadLessons(courseId: number, filter = '', | |
| sortDirection = 'asc', pageIndex = 0, pageSize = 3) { | |
| this.loadingSubject.next(true); | |
| this.coursesService.findLessons(courseId, filter, sortDirection, | |
| pageIndex, pageSize).pipe( | |
| catchError(() => of([])), | |
| finalize(() => this.loadingSubject.next(false)) | |
| ) | |
| .subscribe(lessons => this.lessonsSubject.next(lessons)); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Component({ | |
| selector: 'course', | |
| templateUrl: './course.component.html', | |
| styleUrls: ['./course.component.css'] | |
| }) | |
| export class CourseComponent implements OnInit { | |
| dataSource: LessonsDataSource; | |
| displayedColumns= ["seqNo", "description", "duration"]; | |
| constructor(private coursesService: CoursesService) {} | |
| ngOnInit() { | |
| this.dataSource = new LessonsDataSource(this.coursesService); | |
| this.dataSource.loadLessons(1); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="course"> | |
| <div class="spinner-container" *ngIf="dataSource.loading$ | async"> | |
| <mat-spinner></mat-spinner> | |
| </div> | |
| <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"> | |
| .... | |
| </mat-table> | |
| </div> | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="course"> | |
| <div class="spinner-container" *ngIf="dataSource.loading$ | async"> | |
| <mat-spinner></mat-spinner> | |
| </div> | |
| <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"> | |
| .... | |
| </mat-table> | |
| <mat-paginator [length]="course?.lessonsCount" [pageSize]="3" | |
| [pageSizeOptions]="[3, 5, 10]"></mat-paginator> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Component({ | |
| selector: 'course', | |
| templateUrl: './course.component.html', | |
| styleUrls: ['./course.component.css'] | |
| }) | |
| export class CourseComponent implements AfterViewInit, OnInit { | |
| course:Course; | |
| dataSource: LessonsDataSource; | |
| displayedColumns= ["seqNo", "description", "duration"]; | |
| @ViewChild(MatPaginator) paginator: MatPaginator; | |
| constructor(private coursesService: CoursesService, private route: ActivatedRoute) {} | |
| ngOnInit() { | |
| this.course = this.route.snapshot.data["course"]; | |
| this.dataSource = new LessonsDataSource(this.coursesService); | |
| this.dataSource.loadLessons(this.course.id, '', 'asc', 0, 3); | |
| } | |
| ngAfterViewInit() { | |
| this.paginator.page | |
| .pipe( | |
| tap(() => this.loadLessonsPage()) | |
| ) | |
| .subscribe(); | |
| } | |
| loadLessonsPage() { | |
| this.dataSource.loadLessons( | |
| this.course.id, | |
| '', | |
| 'asc', | |
| this.paginator.pageIndex, | |
| this.paginator.pageSize); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource" | |
| matSort matSortActive="seqNo" matSortDirection="asc" matSortDisableClear> | |
| <ng-container matColumnDef="seqNo"> | |
| <mat-header-cell *matHeaderCellDef mat-sort-header>#</mat-header-cell> | |
| <mat-cell *matCellDef="let lesson">{{lesson.seqNo}}</mat-cell> | |
| </ng-container> | |
| .... | |
| </mat-table> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Component({ | |
| selector: 'course', | |
| templateUrl: './course.component.html', | |
| styleUrls: ['./course.component.css'] | |
| }) | |
| export class CourseComponent implements AfterViewInit, OnInit { | |
| course:Course; | |
| dataSource: LessonsDataSource; | |
| displayedColumns= ["seqNo", "description", "duration"]; | |
| @ViewChild(MatPaginator) paginator: MatPaginator; | |
| @ViewChild(MatSort) sort: MatSort; | |
| constructor(private coursesService: CoursesService, private route: ActivatedRoute) {} | |
| ngOnInit() { | |
| this.course = this.route.snapshot.data["course"]; | |
| this.dataSource = new LessonsDataSource(this.coursesService); | |
| this.dataSource.loadLessons(this.course.id, '', 'asc', 0, 3); | |
| } | |
| ngAfterViewInit() { | |
| // reset the paginator after sorting | |
| this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); | |
| merge(this.sort.sortChange, this.paginator.page) | |
| .pipe( | |
| tap(() => this.loadLessonsPage()) | |
| ) | |
| .subscribe(); | |
| } | |
| loadLessonsPage() { | |
| this.dataSource.loadLessons( | |
| this.course.id, '', this.sort.direction, | |
| this.paginator.pageIndex, this.paginator.pageSize); | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="course"> | |
| <!-- New part: this is the search box --> | |
| <mat-input-container> | |
| <input matInput placeholder="Search lessons" #input> | |
| </mat-input-container> | |
| <div class="spinner-container" *ngIf="dataSource.loading$ | async"> | |
| <mat-spinner></mat-spinner> | |
| </div> | |
| <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource" | |
| matSort matSortActive="seqNo" matSortDirection="asc" matSortDisableClear> | |
| <ng-container matColumnDef="seqNo"> | |
| <mat-header-cell *matHeaderCellDef mat-sort-header>#</mat-header-cell> | |
| <mat-cell *matCellDef="let lesson">{{lesson.seqNo}}</mat-cell> | |
| </ng-container> | |
| <ng-container matColumnDef="description"> | |
| <mat-header-cell *matHeaderCellDef>Description</mat-header-cell> | |
| <mat-cell class="description-cell" | |
| *matCellDef="let lesson">{{lesson.description}}</mat-cell> | |
| </ng-container> | |
| <ng-container matColumnDef="duration"> | |
| <mat-header-cell *matHeaderCellDef>Duration</mat-header-cell> | |
| <mat-cell class="duration-cell" | |
| *matCellDef="let lesson">{{lesson.duration}}</mat-cell> | |
| </ng-container> | |
| <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> | |
| <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row> | |
| </mat-table> | |
| <mat-paginator [length]="course?.lessonsCount" [pageSize]="3" | |
| [pageSizeOptions]="[3, 5, 10]"></mat-paginator> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Component({ | |
| selector: 'course', | |
| templateUrl: './course.component.html', | |
| styleUrls: ['./course.component.css'] | |
| }) | |
| export class CourseComponent implements OnInit, AfterViewInit { | |
| course:Course; | |
| dataSource: LessonsDataSource; | |
| displayedColumns= ["seqNo", "description", "duration"]; | |
| @ViewChild(MatPaginator) paginator: MatPaginator; | |
| @ViewChild(MatSort) sort: MatSort; | |
| @ViewChild('input') input: ElementRef; | |
| constructor( | |
| private route: ActivatedRoute, | |
| private coursesService: CoursesService) {} | |
| ngOnInit() { | |
| this.course = this.route.snapshot.data["course"]; | |
| this.dataSource = new LessonsDataSource(this.coursesService); | |
| this.dataSource.loadLessons(this.course.id, '', 'asc', 0, 3); | |
| } | |
| ngAfterViewInit() { | |
| // server-side search | |
| fromEvent(this.input.nativeElement,'keyup') | |
| .pipe( | |
| debounceTime(150), | |
| distinctUntilChanged(), | |
| tap(() => { | |
| this.paginator.pageIndex = 0; | |
| this.loadLessonsPage(); | |
| }) | |
| ) | |
| .subscribe(); | |
| // reset the paginator after sorting | |
| this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); | |
| // on sort or paginate events, load a new page | |
| merge(this.sort.sortChange, this.paginator.page) | |
| .pipe( | |
| tap(() => this.loadLessonsPage()) | |
| ) | |
| .subscribe(); | |
| } | |
| loadLessonsPage() { | |
| this.dataSource.loadLessons( | |
| this.course.id, | |
| this.input.nativeElement.value, | |
| this.sort.direction, | |
| this.paginator.pageIndex, | |
| this.paginator.pageSize); | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // server-side search | |
| fromEvent(this.input.nativeElement,'keyup') | |
| .pipe( | |
| debounceTime(150), | |
| distinctUntilChanged(), | |
| tap(() => { | |
| this.paginator.pageIndex = 0; | |
| this.loadLessonsPage(); | |
| }) | |
| ) | |
| .subscribe(); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| connect(collectionViewer: CollectionViewer): Observable<Lesson[]> { | |
| return this.lessonsSubject.asObservable(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| disconnect(collectionViewer: CollectionViewer): void { | |
| this.lessonsSubject.complete(); | |
| this.loadingSubject.complete(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| loadLessons(courseId: number, filter = '', | |
| sortDirection = 'asc', pageIndex = 0, pageSize = 3) { | |
| this.loadingSubject.next(true); | |
| this.coursesService.findLessons(courseId, filter, sortDirection, | |
| pageIndex, pageSize).pipe( | |
| catchError(() => of([])), | |
| finalize(() => this.loadingSubject.next(false)) | |
| ) | |
| .subscribe(lessons => this.lessonsSubject.next(lessons)); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ngAfterViewInit() { | |
| this.paginator.page | |
| .pipe( | |
| tap(() => this.loadLessonsPage()) | |
| ) | |
| .subscribe(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="spinner-container" *ngIf="dataSource.loading$ | async"> | |
| <mat-spinner></mat-spinner> | |
| </div> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment