J'essaie de mettre en œuvre table de données Material2 . Mais je ne suis pas capable de comprendre comment l'utiliser correctement.
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() {}
}
Ci-dessus est le code de datatable qui est très déroutant pour moi. Même leur documentation est très pauvre. Quelqu'un peut-il expliquer quel est le flux de code ci-dessus?
S'il vous plaît ignorer si vous pensez que la question est trop élémentaire à poser?
Le code de votre exemple est la définition d'une table générique, qui utilise le nouveau composant cdk dans la spécification material2. vous devez garder à l'esprit que md-table
est l'implémentation visuelle de cdk-table
, vous devez donc déclarer un cdk avec un modèle compatible avec le modèle md en HTML.
Par exemple:
Je déclare un cdk-table
Avec l'implémentation suivante:
Le nouveau composant CDK dans Material2, utilisant:
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';
Je définis un tableau displayedColumns
, les éléments sont les colonnes de mon tableau HTML, dans l'ordre:
displayedColumns = ['userId', 'userName', 'progress'];
Une base de données du type ExampleDatabase
(un objet avec une définition manuelle particulière):
exampleDatabase = new ExampleDatabase();
Enfin, je déclare un dataSource
, c’est l’origine de mes données. C'est un objet avec une définition manuelle ou des données nulles.
dataSource: ExampleDataSource | null;
Dans la méthode ngOnInit()
, je déclare simplement que mon dataSource
est un nouveau ExampleDataSource
avec le paramètre my exampleDataBase
.
Bon, maintenant pour implémenter le reste du code:
Commencez par déclarer une interface pour le DataBase
. Ceci est très important pour maintenir la congruence des données, la base de données doit respecter un schéma défini. Dans cet exemple, la base de données comporte trois colonnes: id, name et progress:
export interface UserData {
id: number;
name: string;
progress: string;
}
Le point suivant est de créer une classe (Object) ExampleDatabase
avec la définition des données dans my DataBase
. Vous pouvez créer un service pour vous connecter à une base de données réelle (PostgreSQL, MongoDB), obtenir les données réelles et créer les objets du cdk-datatable dans une autre méthode. Toutefois, dans cet exemple, nous utilisons une base de données en mémoire émulée au moment de l'exécution.
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()
};
}
}
Bon, enfin je crée une deuxième classe avec la définition de mon 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() { }
}
Cette méthode vérifie que les données sont au format correct et libère la "connexion" vers le DataBase
(en mémoire) pour y récupérer les données.
Enfin, utilisez le composant md-table
Ou cdk-table
Dans le code HTML. Le composant md-table
Utilise le style de conception de matériau et le cdk-table
Utilise un style générique.
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>
Le reste des implémentations, recherche, menus, cases à cocher, etc., vous incombe de mettre en œuvre la logique de manipulation des informations.
Utilisez la documentation sur cdk-table pour plus de détails:
https://material.angular.io/guide/cdk-table
Résultat:
Faites-moi du sabre et de la réussite, je comprends mon explication et je m'excuse pour mon anglais. J'apprends.
Voici le code personnalisé créé pour assister à la vue, pour le moment j’ai codé les données en dur, vous pouvez appeler le service au lieu de cela pour obtenir des données dynamiques.
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 { }
Voici un article écrit par moi. Vous trouverez ici tout ce que vous devez savoir. https://medium.com/@fnote/md-tables-angular-material-be2c45947955
prenons le code pièce par pièce. Vous trouverez le code complet ici 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';
importer les paquets nécessaires dont vous avez besoin. Assurez-vous d’installer angular cdk pendant que vous installez angular). Avant de commencer, il est préférable de mentionner ce qui est une source de données ce qui est observable et ce qui est un comportement sujet et aussi rxjs.
RXJS est un sujet brûlant dans le développement depuis quelques jours. C’est une bibliothèque javascript pour la programmation réactive (la programmation réactive n’est qu’un moyen de créer des applications logicielles. En gros, votre logiciel est conçu pour "réagir" aux changements qui surviennent (comme les événements de clic). , données en cours d'extraction, etc.) à l'aide d'Observables, afin de faciliter la composition de code asynchrone ou basé sur le rappel. cdk est importé parce que les tables md sont construites dessus. Les tables Cdk sont la base des tables md.
Qu'est-ce qu'un observable?
La capacité des observables à gérer plusieurs valeurs au fil du temps en fait un bon candidat pour travailler avec des données en temps réel, des événements et tout type de flux auquel vous pouvez penser. Observables offre un meilleur contrôle lorsque vous travaillez avec un flux entrant de valeurs provenant d'un flux. Observable est un wrapper autour d'une source de données, la source de données est un flux de valeurs pouvant éventuellement émettre plusieurs valeurs au fil du temps, nous souhaitons faire quelque chose à chaque nouvelle valeur. Nous connectons observateur et observable via un abonnement. L'abonnement indique qu'il y a quelqu'un qui écoute ces flux de valeurs. Un observateur s'abonne à un observable. Un observable émet des éléments ou envoie des notifications à ses observateurs en appelant ses méthodes. observer implémente jusqu'à 3 méthodes. elles sont complete (), next () et onerror (). La méthode next () sera appelée par l'observable à chaque fois qu'une nouvelle valeur est émise.Quand l'observable lève une erreur, la méthode onerror () est invoquée.Quand l'observable est terminé et qu'il sait qu'il n'y aura plus de nouvelles valeurs dans le futur appelle la méthode complete ().
Je vous recommande vivement de suivre la série de youtube sur les bibliothèques RXJS de Academind sur YouTube afin de mieux comprendre les fonctionnalités, les observateurs, les observables, les sujets, les sujets de comportement et les abonnements de RXJS.
Continuons avec le code
@Component({
selector: 'table-basic-example',
styleUrls: ['table-basic-example.css'],
templateUrl: 'table-basic-example.html',
})
Ceci est normal angular 4.selector est le nom par lequel les parties extérieures font référence à notre composant. Et style Url est l'emplacement où notre fichier est référencé par ce composant à des fins de style et le code HTML de base du composant est trouvé dans l'URL du modèle.
export class TableBasicExample {
displayedColumns = ['userId', 'userName', 'progress', 'color'];
exampleDatabase = new ExampleDatabase();
dataSource: ExampleDataSource | null;
ngOnInit() {
this.dataSource = new ExampleDataSource(this.exampleDatabase);
}
}
Ici, nous faisons d’abord un tableau de toutes les colonnes de notre table que nous devons afficher sur le navigateur (en-têtes de colonnes). Ce tableau est à nouveau référencé à partir du fichier html.
Et plus loin, nous créons une instance de classe de base de données exemple et une instance de source de données qui ne contient aucune donnée au début. Ensuite, les données de la base de données exemple sont injectées dans cette source de données afin de les remplir car elles sont initialement vides. Ng onitint est un crochet de cycle de vie appelé par angular afin de marquer l'achèvement de la création de le composant.
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'];
Nous avons 2 tableaux qui remplissent notre exemple de base de données
export interface UserData {
id: string;
name: string;
progress: string;
color: string;
}
Ici vous avez une interface définie. Les variables mentionnées ici deviendront éventuellement les colonnes de nos tableaux.
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))]
};
}
}
Il s'agit de la base de données exemple utilisée par la source de données pour extraire les données de la table. Vous avez seulement 2 tableaux définis mais en réalité 4 colonnes à afficher. Vous pouvez remplir 2 colonnes à partir des données des tableaux, mais les données des 2 autres colonnes ici doivent être générées dans cette classe.
Alors, qu'est-ce qu'un sujet? Observable ne peut pas émettre de valeurs, mais nous voulons pouvoir le faire nous-mêmes. Mais si nous devons émettre de nouvelles valeurs nous-mêmes nous devons aller avec un sujet. Subject est un observable dont il hérite mais nous pouvons appeler la méthode next () dessus manuellement pour que nous puissions déclencher l'émission d'une nouvelle valeur. Le sujet est donc un observable actif. C’est un observateur en plus d’être un observable, vous pouvez donc également envoyer des valeurs à un sujet en plus de vous y abonner.
Qu'est-ce que le monde est un sujet comportemental? Le sujet comportemental est un type particulier de sujet mais il a une valeur initiale différente de celle des sujets. Il a besoin d'une valeur initiale car il doit toujours renvoyer une valeur lors de l'abonnement, même s'il n'a pas reçu d'abonnement next () Rx.subject (), rien ne le sera initialement. L'abonnement Rx.behaviorsubject ('a') get 'a' initialement
Ne vous inquiétez pas du code écrit avec le nom const… nous avons environ 20 noms dans le tableau de noms, mais nous avons besoin de 100 noms distincts. Nous modifions donc ici leurs initiales de manière aléatoire.
Les progrès sont également calculés de manière aléatoire.
Le changement de données est une variable de type comportement sujet.
this.dataChange.next(copiedData);
..quand un nouvel utilisateur est poussé dans le tableau pour lequel datachange est notifié aux abonnés. Datachange est une sorte de flux qui émet chaque fois que les données ont été modifiées. Créez une variable appelée datachange qui est un sujet de comportement comportant un tableau de valeurs initiales. Créez un tableau appelé données copiées. Créez un nouvel utilisateur avec 4 propriétés. Les utilisateurs sont créés comme des objets ici avec ces 4 propriétés étant leurs attributs. Appelez la méthode suivante avec le nouvel utilisateur ajouté. Appelez la méthode suivante sur la variable spéciale observable and subject emits.add user () ajoute un utilisateur à la base de données, tandis que la méthode create crée un objet utilisateur avec 4 attributs distincts. Source de données pour indiquer quelles données doivent être rendues dans la table. Notez que la source de données peut récupérer ses données de quelque manière que ce soit. Dans ce cas, la source de données reçoit une référence à une base de données commune, ExampleDatabase. La source de données ne prend que les données et envoie à la table ce qui doit être rendu, rien d'autre.
export class ExampleDataSource extends DataSource<any> {
constructor(private _exampleDatabase: ExampleDatabase) {
super();
}
connect(): Observable<UserData[]> {
return this._exampleDatabase.dataChange;
}
disconnect() {}
}
Connexion de la table à la source de données
Les données sont fournies à la table via une source de données.
La fonction Connect connecte un visualiseur de collection tel qu'une table de données à une source de données. La fonction Connect est appelée par la table pour obtenir le flux contenant les données à restituer. Des paramètres doivent être donnés à cette fonction de connexion. Lorsque la table reçoit une source de données, elle appelle la fonction de connexion de DataSource qui renvoie un observable qui émet un tableau de données. Chaque fois que la source de données émet des données dans ce flux, la table sera mise à jour. Étant donné que la source de données fournit ce flux, il est de la responsabilité de déclencher les mises à jour des tables. Cela peut être basé sur n'importe quoi: connexions de socket Web, interaction utilisateur, mises à jour de modèle, intervalles temporels, etc. Le plus souvent, les mises à jour seront déclenchées par des interactions utilisateur telles que le tri et la pagination. La fonction de déconnexion rompt la connexion entre la table et la source de données. Regardons le fichier HTML ou notre modèle. Modèles de cellules
<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>
Tout d'abord, les colonnes de la table sont définies.avec la directive cdkColumnDef, un nom est attribué à chaque colonne. Il s'agit du nom à partir duquel cette colonne particulière de la table est référée à partir d'autres endroits. Chaque colonne définit ensuite un modèle de cellule d'en-tête et un data cell template.header cell fournit et affiche le nom de la colonne. Le modèle de cellule extrait les données à afficher et les affiche sous l'en-tête, en lignes. cdkCellDef exporte la ligne d'en-tête et la ligne de données sont définies ci-dessous Les modèles de lignes sont donnés ci-dessous,
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
Le tableau ‘Colonnes affichées’ se trouve dans votre fichier .ts (fichier TypeScript) et color est une colonne ou un élément du tableau (comme dans notre exemple). Ces modèles de ligne examinent le nom donné à cdkColumnDef et recherchent les colonnes à restituer. CdkRowDef exporte également le contexte de ligne. Le contenu rendu de la ligne provient des modèles de cellule et non des modèles de ligne. Pour en savoir plus sur cette vérification, consultez la page suivante Angular Material
Edit description material.angular.io comment générer dynamiquement les colonnes requises?
<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>
comparez ce morceau de code avec celui qui précède le dernier .ici, nous parcourons en boucle le tableau displayColumns et les noms de colonne sont attribués dans le processus; nous générons donc les colonnes requises en boucle dans le tableau au lieu de définir toutes les colonnes requises à la main dans le fichier HTML. Avec ceci, je vais conclure cette explication, md tables vous propose également des fonctionnalités telles que la pagination, le tri et le filtrage. La documentation officielle comprend des exemples auxquels vous pouvez vous référer afin d'ajouter ces fonctionnalités à votre table md.
Vous savez maintenant ce qui se passe dans les coulisses d'une table md.
J'ai eu beaucoup de problèmes en essayant d'utiliser cette approche:
import { DataSource } from '@angular/cdk/collections';
....
Je pouvais obtenir la table, mais trier les colonnes était impossible car trier n'était pas une propriété connue de Datasource, etc., etc.
enfin, j'ai remarqué que j'utilisais "@angular/material": "^5.0.0-rc0"
,
Actuel, y je travaille avec MatTableDataSource
IMPORTE
import {MatTableDataSource} from '@angular/material';
VARIABLES DE CLASSE
private ELEMENT_DATA: reportInterface[] = [];
public tbDataSource;
public displayedColumns;
et dans le constructeur
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;
});
et voici mon fonction de filtrage
applyFilter(filterValue: string) {
this.tbDataSource.filter = filterValue;
}
Je pense que c'est plus rapide et plus facile