Reputation: 39373
I'm learning Angular and trying to grasp the concepts. I'm having difficulty doing something that should be simple.
I want to connect a Material Table to a service that downloads some data.
I created my service that downloads some simple data from a website. I created the Data Table using the command line. Now I must change the data source for my service.
Here is the generated file rank-table-datasource.ts
:
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { map } from 'rxjs/operators';
import { Observable, of as observableOf, merge } from 'rxjs';
// TODO: Replace this with your own data model type
export interface RankTableItem {
name: string;
id: number;
}
// TODO: replace this with real data from your application
const EXAMPLE_DATA: RankTableItem[] = [
{id: 1, name: 'Hydrogen'},
{id: 2, name: 'Helium'},
{id: 3, name: 'Lithium'},
{id: 4, name: 'Beryllium'},
{id: 5, name: 'Boron'},
{id: 6, name: 'Carbon'},
{id: 7, name: 'Nitrogen'},
{id: 8, name: 'Oxygen'},
{id: 9, name: 'Fluorine'},
{id: 10, name: 'Neon'},
{id: 11, name: 'Sodium'},
{id: 12, name: 'Magnesium'},
{id: 13, name: 'Aluminum'},
{id: 14, name: 'Silicon'},
{id: 15, name: 'Phosphorus'},
{id: 16, name: 'Sulfur'},
{id: 17, name: 'Chlorine'},
{id: 18, name: 'Argon'},
{id: 19, name: 'Potassium'},
{id: 20, name: 'Calcium'},
];
/**
* Data source for the RankTable view. This class should
* encapsulate all logic for fetching and manipulating the displayed data
* (including sorting, pagination, and filtering).
*/
export class RankTableDataSource extends DataSource<RankTableItem> {
data: RankTableItem[] = EXAMPLE_DATA;
paginator: MatPaginator;
sort: MatSort;
constructor() {
super();
}
/**
* Connect this data source to the table. The table will only update when
* the returned stream emits new items.
* @returns A stream of the items to be rendered.
*/
connect(): Observable<RankTableItem[]> {
// Combine everything that affects the rendered data into one update
// stream for the data-table to consume.
const dataMutations = [
observableOf(this.data),
this.paginator.page,
this.sort.sortChange
];
return merge(...dataMutations).pipe(map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}));
}
/**
* Called when the table is being destroyed. Use this function, to clean up
* any open connections or free any held resources that were set up during connect.
*/
disconnect() {}
/**
* Paginate the data (client-side). If you're using server-side pagination,
* this would be replaced by requesting the appropriate data from the server.
*/
private getPagedData(data: RankTableItem[]) {
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
return data.splice(startIndex, this.paginator.pageSize);
}
/**
* Sort the data (client-side). If you're using server-side sorting,
* this would be replaced by requesting the appropriate data from the server.
*/
private getSortedData(data: RankTableItem[]) {
if (!this.sort.active || this.sort.direction === '') {
return data;
}
return data.sort((a, b) => {
const isAsc = this.sort.direction === 'asc';
switch (this.sort.active) {
case 'name': return compare(a.name, b.name, isAsc);
case 'id': return compare(+a.id, +b.id, isAsc);
default: return 0;
}
});
}
}
/** Simple sort comparator for example ID/Name columns (for client-side sorting). */
function compare(a: string | number, b: string | number, isAsc: boolean) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
I imported my service and my interface:
import { EscolaService } from '../escola.service'
import { Escola } from '../escola';
My Interface also has just an id
and a name
, like the original.
Defined an alias for my type. Don't know if this is the correct way:
export type RankTableItem = Escola;
I should now redefine the connect()
method:
connect(): Observable<RankTableItem[]> {
but I don't know how to do it.
The rank-table-component.html
tries to use some dataSource methods:
<mat-paginator #paginator
[length]="dataSource?.data.length"
[pageIndex]="0"
[pageSize]="50"
[pageSizeOptions]="[25, 50, 100, 250]">
How should I use this connect method and the Observer generated by my Service?
Upvotes: 0
Views: 544
Reputation: 9771
You can use your own datasource like below
a. This is your custom datasource that you defined.
export class RankTableDataSource extends DataSource<RankTableItem> {
//Your rest of the code with connect() and disconnect() methods.
}
b. Then you can consume the above data source in your component like
export class YourComponent implements OnInit, AfterViewInit {
//Take your data source into data bound property
dataSource: RankTableDataSource;
constructor( ) {}
//Initialize your data source in onInit method
ngOnInit() {
this.dataSource = new RankTableDataSource();
}
}
c. Then use this dataSource
into your template.
The connect()
and disconnect()
methods automatically invoked by mat-table data source. You don't need to manually called those methods into your own code if you used custom data source.
Upvotes: 1