mattabledatasource examples example card angular datatable angular-material2

angular - examples - mattabledatasource



Cómo usar la tabla de datos material2 (4)

Estoy tratando de implementar la tabla de datos Material2 . Pero no puedo entender cómo usarlo de manera adecuada.

import {Component, ElementRef, ViewChild} from ''@angular/core''; import {DataSource} from ''@angular/cdk''; import {BehaviorSubject} from ''rxjs/BehaviorSubject''; import {Observable} from ''rxjs/Observable''; import ''rxjs/add/operator/startWith''; import ''rxjs/add/observable/merge''; import ''rxjs/add/operator/map''; import ''rxjs/add/operator/debounceTime''; import ''rxjs/add/operator/distinctUntilChanged''; import ''rxjs/add/observable/fromEvent''; @Component({ selector: ''table-filtering-example'', styleUrls: [''table-filtering-example.css''], templateUrl: ''table-filtering-example.html'', }) export class TableFilteringExample { displayedColumns = [''userId'', ''userName'', ''progress'', ''color'']; exampleDatabase = new ExampleDatabase(); dataSource: ExampleDataSource | null; @ViewChild(''filter'') filter: ElementRef; ngOnInit() { this.dataSource = new ExampleDataSource(this.exampleDatabase); Observable.fromEvent(this.filter.nativeElement, ''keyup'') .debounceTime(150) .distinctUntilChanged() .subscribe(() => { if (!this.dataSource) { return; } this.dataSource.filter = this.filter.nativeElement.value; }); } } /** Constants used to fill up our data base. */ const COLORS = [''maroon'', ''red'', ''orange'', ''yellow'', ''olive'', ''green'', ''purple'', ''fuchsia'', ''lime'', ''teal'', ''aqua'', ''blue'', ''navy'', ''black'', ''gray'']; const NAMES = [''Maia'', ''Asher'', ''Olivia'', ''Atticus'', ''Amelia'', ''Jack'', ''Charlotte'', ''Theodore'', ''Isla'', ''Oliver'', ''Isabella'', ''Jasper'', ''Cora'', ''Levi'', ''Violet'', ''Arthur'', ''Mia'', ''Thomas'', ''Elizabeth'']; export interface UserData { id: string; name: string; progress: string; color: string; } /** An example database that the data source uses to retrieve data for the table. */ export class ExampleDatabase { /** Stream that emits whenever the data has been modified. */ dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]); get data(): UserData[] { return this.dataChange.value; } constructor() { // Fill up the database with 100 users. for (let i = 0; i < 100; i++) { this.addUser(); } } /** Adds a new user to the database. */ addUser() { const copiedData = this.data.slice(); copiedData.push(this.createNewUser()); this.dataChange.next(copiedData); } /** Builds and returns a new User. */ private createNewUser() { const name = NAMES[Math.round(Math.random() * (NAMES.length - 1))] + '' '' + NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + ''.''; return { id: (this.data.length + 1).toString(), name: name, progress: Math.round(Math.random() * 100).toString(), color: COLORS[Math.round(Math.random() * (COLORS.length - 1))] }; } } /** * Data source to provide what data should be rendered in the table. Note that the data source * can retrieve its data in any way. In this case, the data source is provided a reference * to a common data base, ExampleDatabase. It is not the data source''s responsibility to manage * the underlying data. Instead, it only needs to take the data and send the table exactly what * should be rendered. */ export class ExampleDataSource extends DataSource<any> { _filterChange = new BehaviorSubject(''''); get filter(): string { return this._filterChange.value; } set filter(filter: string) { this._filterChange.next(filter); } constructor(private _exampleDatabase: ExampleDatabase) { super(); } /** Connect function called by the table to retrieve one stream containing the data to render. */ connect(): Observable<UserData[]> { const displayDataChanges = [ this._exampleDatabase.dataChange, this._filterChange, ]; return Observable.merge(...displayDataChanges).map(() => { return this._exampleDatabase.data.slice().filter((item: UserData) => { let searchStr = (item.name + item.color).toLowerCase(); return searchStr.indexOf(this.filter.toLowerCase()) != -1; }); }); } disconnect() {} }

Arriba está el código de datos que es muy confuso para mí. Incluso su documentación es muy pobre. ¿Alguien puede explicar cuál es el flujo del código anterior?

Por favor, ignora si sientes que la pregunta es demasiado básica para preguntar?


Aquí está el código personalizado creado para la asistencia de visualización, ahora mismo he codificado los datos, puede llamar al servicio en lugar de eso para obtener datos dinámicos.

app.component.ts

import { Component, OnInit, ElementRef, ViewEncapsulation, ViewChild } from ''@angular/core''; import { DataSource } from ''@angular/cdk''; import { BehaviorSubject } from ''rxjs/BehaviorSubject''; import { Observable } from ''rxjs/Observable''; import { MdPaginator, MdSort } from ''@angular/material''; import ''rxjs/add/operator/startWith''; import ''rxjs/add/observable/merge''; import ''rxjs/add/operator/map''; declare let d3: any; @Component({ selector: ''app-root'', templateUrl: ''./app.component.html'', styleUrls: [''./app.component.css''] }) export class AppComponent implements OnInit { displayedColumns = [''shiftDate'', ''swipeIn'', ''swipeOut'', ''duration'', ''status'']; exampleDatabase = new ExampleDatabase(); dataSource: ExampleDataSource | null; @ViewChild(MdPaginator) paginator: MdPaginator; @ViewChild(MdSort) sort: MdSort; ngOnInit() { this.dataSource = new ExampleDataSource(this.exampleDatabase, this.paginator, this.sort); } } export interface attendanceData { shiftDate: string; swipeIn: string; swipeOut: string; duration: string; status: string; } /** An example database that the data source uses to retrieve data for the table. */ export class ExampleDatabase { /** Stream that emits whenever the data has been modified. */ dataChange: BehaviorSubject<attendanceData[]> = new BehaviorSubject<attendanceData[]>([]); get data(): attendanceData[] { let data = [ { "shiftDate": "17-July-2017", "swipeIn": "10:00 AM", "swipeOut": "06:00 PM", "duration": "8 Hours", "status": "PRESENT" }, { "shiftDate": "16-July-2017", "swipeIn": "9:00 AM", "swipeOut": "5:00 AM", "duration": "7 Hours", "status": "PRESENT" } ]; return data; } constructor() { this.dataChange.next(this.data); } } export class ExampleDataSource extends DataSource<any> { _filterChange = new BehaviorSubject(''''); get filter(): string { return this._filterChange.value; } set filter(filter: string) { this._filterChange.next(filter); } constructor(private _exampleDatabase: ExampleDatabase, private _paginator: MdPaginator, private _sort: MdSort) { super(); } /** Connect function called by the table to retrieve one stream containing the data to render. */ connect(): Observable<attendanceData[]> { const displayDataChanges = [ this._exampleDatabase.dataChange, this._paginator.page, this._sort.mdSortChange ]; return Observable.merge(...displayDataChanges).map(() => { // const data = this._exampleDatabase.data.slice(); const data = this.getSortedData(); // Grab the page''s slice of data. const startIndex = this._paginator.pageIndex * this._paginator.pageSize; return data.splice(startIndex, this._paginator.pageSize); }); } disconnect() { } getSortedData(): attendanceData[] { const data = this._exampleDatabase.data.slice(); if (!this._sort.active || this._sort.direction == '''') { return data; } return data.sort((a, b) => { let propertyA: number | string = ''''; let propertyB: number | string = ''''; switch (this._sort.active) { case ''shiftDate'': [propertyA, propertyB] = [a.shiftDate, b.shiftDate]; break; case ''swipeIn'': [propertyA, propertyB] = [a.swipeIn, b.swipeIn]; break; case ''swipeOut'': [propertyA, propertyB] = [a.swipeOut, b.swipeOut]; break; case ''duration'': [propertyA, propertyB] = [a.duration, b.duration]; break; } let valueA = isNaN(+propertyA) ? propertyA : +propertyA; let valueB = isNaN(+propertyB) ? propertyB : +propertyB; return (valueA < valueB ? -1 : 1) * (this._sort.direction == ''asc'' ? 1 : -1); }); } }

app.component.html

<div class="example-container mat-elevation-z8"> <md-table #table [dataSource]="dataSource" mdSort> <!--- Note that these columns can be defined in any order. The actual rendered columns are set as a property on the row definition" --> <!-- ID Column --> <ng-container cdkColumnDef="shiftDate"> <md-header-cell *cdkHeaderCellDef md-sort-header> Shift Date </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.shiftDate}} </md-cell> </ng-container> <!-- Progress Column --> <ng-container cdkColumnDef="swipeIn"> <md-header-cell *cdkHeaderCellDef md-sort-header> Swipe In </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.swipeIn}}% </md-cell> </ng-container> <!-- Name Column --> <ng-container cdkColumnDef="swipeOut"> <md-header-cell *cdkHeaderCellDef> Swipe Out </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.swipeOut}} </md-cell> </ng-container> <!-- Color Column --> <ng-container cdkColumnDef="duration"> <md-header-cell *cdkHeaderCellDef>Duration</md-header-cell> <md-cell *cdkCellDef="let row"> {{row.duration}} </md-cell> </ng-container> <!-- Color Column --> <ng-container cdkColumnDef="status"> <md-header-cell *cdkHeaderCellDef>Status</md-header-cell> <md-cell *cdkCellDef="let row"> {{row.status}} </md-cell> </ng-container> <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row> <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row> </md-table> <md-paginator #paginator [length]="exampleDatabase.data.length" [pageIndex]="0" [pageSize]="25" [pageSizeOptions]="[5, 10, 25, 100]"> </md-paginator> </div>

app.module.ts

import { platformBrowserDynamic } from ''@angular/platform-browser-dynamic''; import { BrowserModule } from ''@angular/platform-browser''; import { BrowserAnimationsModule } from ''@angular/platform-browser/animations''; import { NgModule } from ''@angular/core''; import { MaterialModule, MdTableModule } from ''@angular/material''; import { FlexLayoutModule } from ''@angular/flex-layout''; import { CdkTableModule } from ''@angular/cdk''; import { AppComponent } from ''./app.component''; @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserAnimationsModule, CdkTableModule, BrowserModule, MaterialModule, MdTableModule, FlexLayoutModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }


Aquí hay un artículo escrito por mí. Encontrará todo lo que necesita saber aquí. https://medium.com/@fnote/md-tables-angular-material-be2c45947955

Tomemos el código pieza por pieza. Encontrará el código completo aquí https://material.angular.io/components/table/overview

import {Component} from ''@angular/core''; import {DataSource} from ''@angular/cdk''; import {BehaviorSubject} from ''rxjs/BehaviorSubject''; import {Observable} from ''rxjs/Observable''; import ''rxjs/add/operator/startWith''; import ''rxjs/add/observable/merge''; import ''rxjs/add/operator/map'';

Importa los paquetes necesarios que necesites. Asegúrese de instalar angular cdk mientras instala material angular. Antes de continuar, es mejor mencionar qué es una fuente de datos, qué es un sujeto observable y qué es un tema de comportamiento y también rxjs.

RXJS es un tema candente en el desarrollo de frond end en estos días. Es una biblioteca javascript para programación reactiva (la programación reactiva es solo una forma de crear aplicaciones de software. Esencialmente, su software está diseñado para "reaccionar" a los cambios que ocurren (como eventos de clic , datos que se están buscando, etc.) utilizando Observables, para facilitar la composición de código asíncrono o basado en devolución de llamada. cdk se importa porque las tablas md están construidas sobre él. Las tablas cdk son la base de las tablas md.

¿Qué es un observable?

La capacidad de los observables de poder manejar múltiples valores a lo largo del tiempo los convierte en un buen candidato para trabajar con datos en tiempo real, eventos y cualquier tipo de flujo que pueda imaginar. Los observables proporcionan un mejor control cuando se trabaja con el flujo de valores de un flujo. Observable es una envoltura alrededor de una fuente de datos, la fuente de datos es un flujo de valores que posiblemente emita múltiples valores a lo largo del tiempo que queremos hacer cuando se produce un nuevo valor. Conectamos observador y observable a través de una suscripción. La suscripción dice que hay alguien escuchando estos flujos de valores. Un observador se suscribe a un observable. Un observable emite elementos o envía notificaciones a sus observadores llamando a los métodos de los observadores. Observer implementa hasta 3 métodos. Son completos (), next () y onerror (). El método next () será llamado por el observable siempre que se emita un nuevo valor. Cada vez que observable arroja un error, se invoca el método onerror (). Cuando se hace observable y cuando se sabe, no habrá más valores nuevos en el futuro. Llama al método complete ().

Recomiendo encarecidamente que siga la serie académica en youtube sobre la biblioteca RXJS para obtener una comprensión más profunda sobre las capacidades, observadores, observables, sujetos, temas de comportamiento y suscripciones de RXJS.

Continuemos con el código.

@Component({ selector: ''table-basic-example'', styleUrls: [''table-basic-example.css''], templateUrl: ''table-basic-example.html'', })

Este es un 4.selector angular regular es el nombre con el que las partes externas se refieren a nuestro componente. Y Url de estilo es la ubicación a la que se refiere nuestro archivo de componente con fines de estilo y el código básico del componente se encuentra en la url de la plantilla.

export class TableBasicExample { displayedColumns = [''userId'', ''userName'', ''progress'', ''color'']; exampleDatabase = new ExampleDatabase(); dataSource: ExampleDataSource | null; ngOnInit() { this.dataSource = new ExampleDataSource(this.exampleDatabase); } }

Aquí, primero, hacemos una matriz de todas las columnas de nuestra tabla que necesitamos mostrar en el navegador (encabezados de columna). Esta matriz es referida nuevamente desde el archivo html.

Y además, creamos una instancia de la clase de base de datos de ejemplo y una instancia de fuente de datos que no lleva datos al principio. Luego, los datos de la base de datos de ejemplo se inyectan en esta fuente de datos para rellenarlos, ya que inicialmente están vacíos. Ng onitint es un gancho del ciclo de vida al que se llama angular para marcar la finalización de la creación del componente.

const COLORS = [''maroon'', ''red'', ''orange'', ''yellow'', ''olive'', ''green'', ''purple'',''fuchsia'', ''lime'', ''teal'', ''aqua'', ''blue'', ''navy'', ''black'', ''gray'']; const NAMES = [''Maia'', ''Asher'', ''Olivia'', ''Atticus'', ''Amelia'', ''Jack'',''Charlotte'', ''Theodore'', ''Isla'', ''Oliver'', ''Isabella'', ''Jasper'',''Cora'', ''Levi'', ''Violet'', ''Arthur'', ''Mia'', ''Thomas'', ''Elizabeth''];

Tenemos 2 arreglos. Estos llenan nuestra base de datos de ejemplo.

export interface UserData { id: string; name: string; progress: string; color: string; }

Aquí tienes una interfaz definida. Las variables mencionadas aquí eventualmente se convertirán en las columnas de nuestras tablas.

export class ExampleDatabase { dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]> ([]); get data(): UserData[] { return this.dataChange.value; } constructor() { // Fill up the database with 100 users. for (let i = 0; i < 100; i++) { this.addUser(); } } addUser() { const copiedData = this.data.slice(); copiedData.push(this.createNewUser()); this.dataChange.next(copiedData); } private createNewUser() { const name = NAMES[Math.round(Math.random() * (NAMES.length - 1))] + '' '' + NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + ''.''; return { id: (this.data.length + 1).toString(), name: name, progress: Math.round(Math.random() * 100).toString(), color: COLORS[Math.round(Math.random() * (COLORS.length - 1))] }; } }

Esta es la base de datos de ejemplo que la fuente de datos utiliza para recuperar datos para la tabla. Solo tiene 2 matrices definidas pero, de hecho, 4 columnas para mostrar. Puede llenar 2 columnas de los datos en los arreglos, pero los datos para las otras 2 columnas aquí deben generarse dentro de esta clase.

Entonces, ¿qué es un tema? Lo observable no puede emitir valores en sí mismo, pero queremos poder hacerlo nosotros mismos. Pero si necesitamos emitir nuevos valores, debemos ir con un tema. El sujeto es un observable que hereda de observable, pero podemos invocar el método next () manualmente, ya que podemos activar la emisión de un nuevo valor. Por lo tanto el sujeto es un observable activo. Es un observador además de ser un observable, por lo que también puede enviar valores a un sujeto además de suscribirse a él.

¿Qué en el mundo es un sujeto de comportamiento? El sujeto de comportamiento es un tipo especial de sujeto, pero tiene un valor inicial a diferencia de los sujetos. Necesita un valor inicial, ya que siempre debe devolver un valor en la suscripción, incluso si no ha recibido una suscripción siguiente () Rx.subject () no obtendrá nada inicialmente. La suscripción Rx.behaviorsubject (''a'') obtiene ''a'' inicialmente

No se preocupe por el código escrito con el nombre de const ... tenemos alrededor de 20 nombres en la matriz de nombres, pero necesitamos 100 nombres distintos. Así que aquí cambiamos sus iniciales en un patrón aleatorio.

El progreso también se calcula al azar.

El cambio de datos es una variable de tipo comportamiento del sujeto.

this.dataChange.next(copiedData);

... siempre que un nuevo usuario se inserta en la matriz, ese cambio de datos se notifica a los suscriptores. Datachange es una especie de Stream que se emite cada vez que se modifican los datos. Cree una variable llamada cambio de datos que sea un sujeto de comportamiento que tenga una matriz de valores iniciales Cree una matriz llamada datos copiados Cree un nuevo usuario con 4 propiedades. Los usuarios se crean como objetos aquí con estas 4 propiedades siendo sus atributos. Llame al siguiente método con el nuevo usuario agregado Llame al siguiente método en el usuario especial emits.add observable y sujeto agrega un usuario a la base de datos mientras crea el método de usuario crea un objeto de usuario con 4 atributos distintos. Fuente de datos para proporcionar los datos que se deben representar en la tabla. Tenga en cuenta que la fuente de datos puede recuperar sus datos de cualquier manera. En este caso, la fuente de datos se proporciona una referencia a una base de datos común, ExampleDatabase. La fuente de datos solo toma los datos y envía a la tabla exactamente lo que se debe representar, nada más.

export class ExampleDataSource extends DataSource<any> { constructor(private _exampleDatabase: ExampleDatabase) { super(); } connect(): Observable<UserData[]> { return this._exampleDatabase.dataChange; } disconnect() {} }

Conectando la tabla al origen de datos

Los datos se proporcionan a la tabla a través de un DataSource.

La función Conectar conecta un visor de colecciones, como una tabla de datos, a una fuente de datos. La tabla llama a la función de conexión para obtener el flujo que contiene los datos que se deben representar. Se deben dar parámetros a esta función de conexión. Cuando la tabla recibe un origen de datos, llama a la función de conexión de DataSource que devuelve un observable que emite una matriz de datos. Siempre que el origen de datos emita datos a esta secuencia, la tabla se actualizará. Debido a que la fuente de datos proporciona este flujo, es responsable de activar las actualizaciones de la tabla. Esto puede basarse en cualquier cosa: conexiones de socket web, interacción con el usuario, actualizaciones de modelos, intervalos basados ​​en el tiempo, etc. En la mayoría de los casos, las actualizaciones se activarán mediante interacciones del usuario como la clasificación y la paginación. La función de desconexión rompe la conexión entre la tabla y la fuente de datos. Veamos el archivo HTML o nuestra plantilla. Plantillas de celdas

<ng-container cdkColumnDef="color"> <md-header-cell *cdkHeaderCellDef>Color</md-header-cell> <md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </md-cell> </ng-container>

En primer lugar, se definen las columnas de la tabla. Con la directiva cdkColumnDef a cada columna se le asigna un nombre. Este es el nombre desde el cual se hace referencia a esta columna en particular de la tabla. Luego, cada columna continúa definiendo una plantilla de celda de encabezado y una data cell template.header cell proporciona y muestra el nombre de la columna y la plantilla de celda recupera los datos que deben mostrarse y los muestra debajo del encabezado en filas. cdkCellDef exporta la fila de encabezado de las tablas de contexto y la fila de datos se definen a continuación a continuación se muestran las Plantillas de fila,

<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row> <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>

La matriz de ''Columnas mostradas'' se encuentra en su archivo .ts (archivo mecanografiado) y el color es una columna o un elemento de la matriz (según nuestro ejemplo). Estas plantillas de fila miran el nombre dado a cdkColumnDef y encuentran las columnas específicas para representar. El cdkRowDef también exporta el contexto de la fila. El contenido representado de la fila proviene de las plantillas de celda, no de las plantillas de fila. Para leer más sobre esto mira esto Material Angular

Editar descripción material.angular.io ¿cómo generar columnas requeridas dinámicamente?

<ng-container *ngFor="let col of displayedColumns" cdkColumnDef= {{col}}> <md-header-cell *cdkHeaderCellDef md-sort-header > {{ col }} </md-header- cell> <md-cell *cdkCellDef="let row"> {{row[col]}} </md-cell> </ng-container>

compare este fragmento de código con el anterior al anterior. aquí repasamos la matriz de columnas mostradas y los nombres de las columnas se asignan en el proceso, por lo tanto, generamos las columnas necesarias que recorren la matriz en lugar de definir manualmente todas las columnas requeridas en el archivo HTML. Con esto concluiré esta explicación, md tables le ofrece funciones como paginación, clasificación y filtrado. La documentación oficial incluye ejemplos a los que puede referirse para agregar estas características a su tabla md.

Ahora sabes lo que sucede detrás de las escenas en una mesa md.


El código de su ejemplo es la definición de una tabla genérica, utilizando el nuevo componente cdk en la especificación material2. debe tener en cuenta que md-table es la implementación visual de cdk-table , por lo que debe declarar un cdk con un modelo compatible con md-model en HTML.

Por ejemplo:

Declaro una cdk-table con la siguiente implementación:

  1. Primero, las dependencias:

El nuevo componente CDK en Material2, utilizando:

import { DataSource } from ''@angular/cdk''; import { BehaviorSubject } from ''rxjs/BehaviorSubject''; import { Observable } from ''rxjs/Observable''; import ''rxjs/add/operator/startWith''; import ''rxjs/add/observable/merge''; import ''rxjs/add/operator/map'';

  1. Definición de la estructura del HTML en TS:

Defino una matriz de columnas displayedColumns , los elementos son las columnas en mi tabla HTML, en orden:

displayedColumns = [''userId'', ''userName'', ''progress''];

Una base de datos del tipo ExampleDatabase (un objeto con una definición manual en particular):

exampleDatabase = new ExampleDatabase();

Finalmente, declaro una dataSource , este es el origen de mis datos. Es un objeto con una definición manual o datos nulos.

dataSource: ExampleDataSource | null;

En el método ngOnInit() , simplemente declaro que mi dataSource es una nueva ExampleDataSource con el parámetro mi base de datos de exampleDataBase .

Bien, ahora a implementar el resto del código:

Primero, declare una interfaz para la base de datos. Esto es muy importante para mantener la congruencia de los datos, la base de datos debe respetar un esquema definido. En este ejemplo, la base de datos tiene tres columnas: id, nombre y progreso:

export interface UserData { id: number; name: string; progress: string; }

El siguiente punto es crear una ExampleDatabase de datos de ExampleDatabase clase (objeto) con la definición de los datos en mi base de datos. Podría crear un servicio para conectarse a una base de datos real (PostgreSQL, MongoDB), obtener los datos reales y crear los objetos para el cdk-datatable en otro método, sin embargo, en este ejemplo estamos usando una base de datos en memoria emulada en tiempo de ejecución.

export class ExampleDatabase { /** Stream that emits whenever the data has been modified. */ dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]); get data(): UserData[] { return this.dataChange.value; } constructor() { // Fill up the database with 100 users. for (let i = 0; i < 100; i++) { this.addUser(); } } /** Adds a new user to the database. */ addUser() { const copiedData = this.data.slice(); copiedData.push(this.createNewUser()); this.dataChange.next(copiedData); } /** Builds and returns a new User. */ private createNewUser() { return { id: 1, name: ''example'', progress: Math.round(Math.random() * 100).toString() }; } }

Bien, finalmente creo una segunda clase con la definición de mi DataSource .

export class ExampleDataSource extends DataSource<any> { constructor(private _exampleDatabase: ExampleDatabase) { super(); } /** Connect function called by the table to retrieve one stream containing the data to render. */ connect(): Observable<UserData[]> { return this._exampleDatabase.dataChange; } disconnect() { } }

Este método se asegura de que los datos estén en el formato correcto y libera la "conexión" a la DataBase (en la memoria) para obtener los datos que contiene.

Finalmente, use el componente md-table o el componente cdk-table en el HTML. El componente md-table usa el estilo de diseño del material, y la cdk-table usa un estilo genérico.

md-table:

<div class="example-container mat-elevation-z8"> <md-table #table [dataSource]="dataSource"> <!-- ID Column --> <ng-container cdkColumnDef="userId"> <md-header-cell *cdkHeaderCellDef> ID </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.id}} </md-cell> </ng-container> <!-- Progress Column --> <ng-container cdkColumnDef="progress"> <md-header-cell *cdkHeaderCellDef> Progress </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell> </ng-container> <!-- Name Column --> <ng-container cdkColumnDef="userName"> <md-header-cell *cdkHeaderCellDef> Name </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.name}} </md-cell> </ng-container> <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row> <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row> </md-table> </div>

cdk-table:

<div class="example-container mat-elevation-z8"> <cdk-table #table [dataSource]="dataSource" class="example-table"> <!-- ID Column --> <ng-container cdkColumnDef="userId"> <cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> ID </cdk-header-cell> <cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.id}} </cdk-cell> </ng-container> <!-- Progress Column --> <ng-container cdkColumnDef="progress"> <cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> Progress </cdk-header-cell> <cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.progress}}% </cdk-cell> </ng-container> <!-- Name Column --> <ng-container cdkColumnDef="userName"> <cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> Name </cdk-header-cell> <cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.name}} </cdk-cell> </ng-container> <cdk-header-row *cdkHeaderRowDef="displayedColumns" class="example-header-row"></cdk-header-row> <cdk-row *cdkRowDef="let row; columns: displayedColumns;" class="example-row"></cdk-row> </cdk-table> </div>

El resto de implementaciones, búsquedas, menús, casillas de verificación, etc., es su responsabilidad de implementar la lógica para manipular la información.

Use la documentación sobre cdk-table para más detalles:

https://material.angular.io/guide/cdk-table

Resultado:

Hazme saber y logro, comprendo mi explicación y te pido disculpas por mi inglés. Estoy aprendiendo.


Tuve muchos problemas tratando de usar este enfoque:

import { DataSource } from ''@angular/cdk/collections'';

....

Podría obtener la tabla, pero ordenar las columnas era imposible porque ordenar no era una propiedad conocida de Datasource, etc, etc.

Finalmente noté que estaba usando "@angular/material": "^5.0.0-rc0" ,

Actual, y estoy trabajando con MatTableDataSource

IMPORTACIONES

import {MatTableDataSource} from ''@angular/material'';

VARIABLES DE CLASE

private ELEMENT_DATA: reportInterface[] = []; public tbDataSource; public displayedColumns;

y en el constructor

this.dataService.getReport().subscribe(results => { if(!results)return; this.ELEMENT_DATA = results; this.displayedColumns = [.............]; this.tbDataSource = new MatTableDataSource(this.ELEMENT_DATA); this.tbDataSource.sort = this.sort; });

y aquí está mi función de filtro

applyFilter(filterValue: string) { this.tbDataSource.filter = filterValue; }

Creo que esto es más rápido y más fácil.