Angular + Material - Comment actualiser une source de données (mat-table)


120

J'utilise un mat-table pour lister le contenu des langues choisies par les utilisateurs. Ils peuvent également ajouter de nouvelles langues à l'aide du panneau de dialogue. Après avoir ajouté une langue et sont revenus. Je souhaite que ma source de données s'actualise pour afficher les modifications apportées.

J'initialise le magasin de données en récupérant les données utilisateur d'un service et en les transmettant à une source de données dans la méthode d'actualisation.

Language.component.ts

import { Component, OnInit } from '@angular/core';
import { LanguageModel, LANGUAGE_DATA } from '../../../../models/language.model';
import { LanguageAddComponent } from './language-add/language-add.component';
import { AuthService } from '../../../../services/auth.service';
import { LanguageDataSource } from './language-data-source';
import { LevelbarComponent } from '../../../../directives/levelbar/levelbar.component';
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { MatSnackBar, MatDialog } from '@angular/material';

@Component({
  selector: 'app-language',
  templateUrl: './language.component.html',
  styleUrls: ['./language.component.scss']
})
export class LanguageComponent implements OnInit {

  displayedColumns = ['name', 'native', 'code', 'level'];
  teachDS: any;
  user: any;

  constructor(private authService: AuthService, private dialog: MatDialog) { }

  ngOnInit() {
    this.refresh();
  }

  add() {
    this.dialog.open(LanguageAddComponent, {
      data: { user: this.user },
    }).afterClosed().subscribe(result => {
      this.refresh();
    });
  }

  refresh() {
    this.authService.getAuthenticatedUser().subscribe((res) => {
      this.user = res;
      this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);   
    });
  }
}

source-de-données-langue.ts

import {MatPaginator, MatSort} from '@angular/material';
import {DataSource} from '@angular/cdk/collections';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';

export class LanguageDataSource extends DataSource<any> {

  constructor(private languages) {
    super();
  }

  connect(): Observable<any> {
    return Observable.of(this.languages);
  }

  disconnect() {
    // No-op
  }

}

J'ai donc essayé d'appeler une méthode d'actualisation où j'obtiens à nouveau l'utilisateur du backend, puis je réinitialise la source de données. Cependant, cela ne fonctionne pas, aucun changement ne se produit.


1
Si vous souhaitez déclencher le changement "à partir de la source de données", veuillez consulter stackoverflow.com/questions/47897694
...

Des émetteurs d'événements peuvent être utilisés dans ce cas. stackoverflow.com/a/44858648/8300620
Rohit Parte

Réponses:


58

Déclenchez une détection de changement en utilisant ChangeDetectorRefdans la refresh()méthode juste après avoir reçu les nouvelles données, injectez ChangeDetectorRef dans le constructeur et utilisez detectChanges comme ceci:

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { LanguageModel, LANGUAGE_DATA } from '../../../../models/language.model';
import { LanguageAddComponent } from './language-add/language-add.component';
import { AuthService } from '../../../../services/auth.service';
import { LanguageDataSource } from './language-data-source';
import { LevelbarComponent } from '../../../../directives/levelbar/levelbar.component';
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { MatSnackBar, MatDialog } from '@angular/material';

@Component({
  selector: 'app-language',
  templateUrl: './language.component.html',
  styleUrls: ['./language.component.scss']
})
export class LanguageComponent implements OnInit {
  displayedColumns = ['name', 'native', 'code', 'level'];
  teachDS: any;

  user: any;

  constructor(private authService: AuthService, private dialog: MatDialog,
              private changeDetectorRefs: ChangeDetectorRef) { }

  ngOnInit() {
    this.refresh();
  }

  add() {
    this.dialog.open(LanguageAddComponent, {
      data: { user: this.user },
    }).afterClosed().subscribe(result => {
      this.refresh();
    });
  }

  refresh() {
    this.authService.getAuthenticatedUser().subscribe((res) => {
      this.user = res;
      this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);
      this.changeDetectorRefs.detectChanges();
    });
  }
}

9
Cela semble fonctionner, est-ce la bonne façon de procéder? Semble un peu hacky ...
Kay

Quels sont les autres moyens? Pourriez-vous fournir des exemples dans votre solution pour une réponse complète?
Kay


88

Je ne sais pas si le ChangeDetectorRefétait requis lors de la création de la question, mais maintenant cela suffit:

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

refresh() {
  this.myService.doSomething().subscribe((data: MyDataType[]) => {
    this.dataSource.data = data;
  }
}

Exemple:
StackBlitz


4
Bien que cette solution fonctionne en fait, elle gâche le paginateur de matériaux si l'élément est ajouté ailleurs que dans la première page de résultats. Je comprends que cela dépasse le cadre de cette question, mais comme les deux sont liés, avez-vous une solution rapide à ce problème que vous pourriez ajouter à votre réponse?
Knight

5
@Knight Je pense que vous devez affecter le Paginator à la MatTableDataSource.paginatorpropriété une fois que la vue du Paginator a été initialisée. Voir la description de la paginatorpropriété ici: material.angular.io/components/table/api#MatTableDataSource
Martin Schneider

Bonne référence. Je n'avais pas remarqué cela dans les documents auparavant. Merci!
Knight

2
@ MA-Maddin pouvez-vous être plus précis sur la façon de le faire? exemple?
Nathanphan

@Nathanphan en retard, mais a ajouté un exemple;)
Martin Schneider

46

Donc pour moi, personne n'a donné la bonne réponse au problème que j'ai rencontré qui est presque le même que @Kay. Pour moi, il s'agit de trier, le tri de la table ne se produit pas de changements dans le tapis. Je propose cette réponse car c'est le seul sujet que je trouve en cherchant sur google. J'utilise Angular 6.

Comme dit ici :

Étant donné que la table optimise les performances, elle ne vérifiera pas automatiquement les modifications apportées au tableau de données. Au lieu de cela, lorsque des objets sont ajoutés, supprimés ou déplacés sur le tableau de données, vous pouvez déclencher une mise à jour des lignes rendues de la table en appelant sa méthode renderRows ().

Il vous suffit donc d'appeler renderRows () dans votre méthode refresh () pour que vos modifications apparaissent.

Voir ici pour l'intégration.


1
Si la source de données de la table est modifiée sur le client, cette réponse est probablement celle que vous recherchez. Fonctionne très bien!
Alvin Saldanha

C'est la bonne réponse à partir du matériau angulaire 8
Tom

Je vous remercie. Mais à partir de quel objet dois-je appeler le "renderRows ()"? Est-ce dans «this.datasource»?
WitnessTruth

19

Puisque vous utilisez MatPaginator, il vous suffit de modifier le paginateur, cela déclenche le rechargement des données.

Astuce simple:

this.paginator._changePageSize(this.paginator.pageSize); 

Cela met à jour la taille de la page à la taille de la page actuelle, donc fondamentalement rien ne change, sauf que la _emitPageEvent()fonction privée est également appelée, déclenchant le rechargement de la table.


J'ai essayé votre code et cela ne fonctionne pas (n'a aucun effet). Cependant nextPage puis previousPage fonctionnent à nouveau, mais ne constituent pas une solution.
Ahmed Hasn.

_changePageSize()n'est-ce pas public? Est-il sûr à utiliser? Plus d'informations sur stackoverflow.com/questions/59093781/…
Jones

9
this.dataSource = new MatTableDataSource<Element>(this.elements);

Ajoutez cette ligne sous votre action d'ajout ou de suppression de la ligne particulière.

refresh() {
  this.authService.getAuthenticatedUser().subscribe((res) => {
    this.user = new MatTableDataSource<Element>(res);   
  });
}

what is this.elements
parvat

8

La meilleure façon de procéder consiste à ajouter un observable supplémentaire à votre implémentation de source de données.

Dans la méthode de connexion, vous devriez déjà utiliser Observable.mergepour vous abonner à un tableau d'observables qui incluent paginator.page, sort.sortChange, etc. Vous pouvez ajouter un nouveau sujet à celui-ci et appeler le suivant lorsque vous devez provoquer une actualisation.

quelque chose comme ça:

export class LanguageDataSource extends DataSource<any> {

    recordChange$ = new Subject();

    constructor(private languages) {
      super();
    }

    connect(): Observable<any> {

      const changes = [
        this.recordChange$
      ];

      return Observable.merge(...changes)
        .switchMap(() => return Observable.of(this.languages));
    }

    disconnect() {
      // No-op
    }
}

Et puis vous pouvez appeler recordChange$.next()pour lancer une actualisation.

Naturellement, j'emballerais l'appel dans une méthode refresh () et l'appellerais hors de l'instance de source de données avec le composant et d'autres techniques appropriées.


Cette méthode peut être la bonne manière. Cela fonctionne bien pour moi
Manu

comment mettre en œuvre cela lorsque je souhaite étendre MatTableDataSource? Quand j'essaye votre exemple de code, j'obtiens l'erreurProperty 'connect' in type 'customDataSource<T>' is not assignable to the same property in base type 'MatTableDataSource<T>'. Type '() => Observable<any>' is not assignable to type '() => BehaviorSubject<T[]>'. Type 'Observable<any>' is not assignable to type 'BehaviorSubject<T[]>'. Property '_value' is missing in type 'Observable<any>'.
Maurice

1
@Maurice le type MatTableDataSource implémente la méthode de connexion avec un type de retour différent. Il utilise BehaviorSubject <t []> ce qui signifie que vous avez juste besoin de modifier l'exemple pour renvoyer ceci au lieu d'un observable. Vous devriez toujours pouvoir utiliser DataSource, mais si vous devez utiliser MatTableDataSource, renvoyez un BehaviorSubject abonné à votre observable, en supposant que vous en ayez un pour commencer. J'espère que cela pourra aider. Vous pouvez vous référer à la source de MatTableDataSource pour la syntaxe exacte du nouveau type de source de données: github.com/angular/material2/blob/master/src/lib/table/…
jogi

7

Vous pouvez simplement utiliser la fonction de connexion à la source de données

this.datasource.connect().next(data);

ainsi. 'data' étant les nouvelles valeurs de la table de données


Avait du potentiel mais ne semble pas fonctionner. Si après cela vous accédez à this.datasource.data, il n'est pas mis à jour.
Rui Marques du

4

Vous pouvez facilement mettre à jour les données de la table en utilisant "concat":

par exemple:

language.component.ts

teachDS: any[] = [];

language.component.html

<table mat-table [dataSource]="teachDS" class="list">

Et, lorsque vous mettez à jour les données (language.component.ts):

addItem() {
    // newItem is the object added to the list using a form or other way
    this.teachDS = this.teachDS.concat([newItem]);
 }

Lorsque vous utilisez angular "concat", détectez les changements de l'objet (this.teachDS) et vous n'avez pas besoin d'utiliser autre chose.

PD: Cela fonctionne pour moi en angulaire 6 et 7, je n'ai pas essayé une autre version.


2
Oui, cela fonctionne pour moi, c'est un problème concernant la référence et la valeur var, la détection de changement ne voit pas les nouveaux changements, pour cela vous devez le mettre à jour.
Mayra Rodriguez

Cela peut fonctionner si le dataSource est juste un tableau mais pas lorsque dataSource est un objet MatTableDataSource.
Rui Marques


3

Eh bien, j'ai rencontré un problème similaire où j'ai ajouté quelque chose à la source de données et ce n'est pas en cours de rechargement.

Le moyen le plus simple que j'ai trouvé était simplement de réaffecter les données

let dataSource = ['a','b','c']
dataSource.push('d')
let cloned = dataSource.slice()
// OR IN ES6 // let cloned = [...dataSource]
dataSource = cloned

Parfait!! Il wokrs !! Merci :)
Nicolas

3

Dans Angular 9, le secret est this.dataSource.data = this.dataSource.data;

Exemple:

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

dataSource: MatTableDataSource<MyObject>;

refresh(): void {
    this.applySomeModif();
    // Do what you want with dataSource

    this.dataSource.data = this.dataSource.data;
}

applySomeModif(): void {
    // add some data
    this.dataSource.data.push(new MyObject());
    // delete index number 4
    this.dataSource.data.splice(4, 0);
}

2

J'ai réalisé une bonne solution en utilisant deux ressources:

actualisation à la fois de la source de données et du paginateur:

this.dataSource.data = this.users;
this.dataSource.connect().next(this.users);
this.paginator._changePageSize(this.paginator.pageSize);

où par exemple dataSource est défini ici:

    users: User[];
    ...
    dataSource = new MatTableDataSource(this.users);
    ...
    this.dataSource.paginator = this.paginator;
    ...

1
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

export class LanguageComponent implemnts OnInit {
  displayedColumns = ['name', 'native', 'code', 'leavel'];
  user: any;
  private update = new Subject<void>();
  update$ = this.update.asObservable();

  constructor(private authService: AuthService, private dialog: MatDialog) {}

   ngOnInit() {
     this.update$.subscribe(() => { this.refresh()});
   }

   setUpdate() {
     this.update.next();
   }

   add() {
     this.dialog.open(LanguageAddComponent, {
     data: { user: this.user },
   }).afterClosed().subscribe(result => {
     this.setUpdate();
   });
 }

 refresh() {
   this.authService.getAuthenticatedUser().subscribe((res) => {
     this.user = res;
     this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);   
    });
  }
}

8
Veuillez ajouter une explication à votre réponse, le simple fait de publier le code n'est pas très utile et peut entraîner la suppression de votre réponse.
TJ Wolschon

1

dans mon cas (Angular 6+), j'ai hérité de MatTableDataSourcecréer MyDataSource. Sans appeler aprèsthis.data = someArray

this.entitiesSubject.next(this.data as T[])

les données ne sont pas affichées

classe MyDataSource

export class MyDataSource<T extends WhateverYouWant> extends MatTableDataSource<T> {

    private entitiesSubject = new BehaviorSubject<T[]>([]);


    loadDataSourceData(someArray: T[]){
        this.data = someArray //whenever it comes from an API asyncronously or not
        this.entitiesSubject.next(this.data as T[])// Otherwise data not displayed
    }

    public connect(): BehaviorSubject<T[]> {
        return this.entitiesSubject
    }

}//end Class 

1

Il y a deux façons de le faire car le matériau angulaire est incohérent, et cela est très mal documenté. La table des matériaux angulaires ne sera pas mise à jour lorsqu'une nouvelle ligne arrivera. Étonnamment, on dit que c'est à cause de problèmes de performance. Mais cela ressemble plus à un problème de conception, ils ne peuvent pas changer. Il faut s'attendre à ce que la table se mette à jour lorsqu'une nouvelle ligne apparaît. Si ce comportement ne doit pas être activé par défaut, il doit y avoir un commutateur pour le désactiver.

Quoi qu'il en soit, nous ne pouvons pas changer de matériau angulaire. Mais nous pouvons essentiellement utiliser une méthode très mal documentée pour le faire:

Un - si vous utilisez un tableau directement comme source:

call table.renderRows()

où table est ViewChild du mat-table

Deuxièmement - si vous utilisez le tri et d'autres fonctionnalités

table.renderRows () ne fonctionnera étonnamment pas. Parce que mat-table est incohérent ici. Vous devez utiliser un hack pour indiquer que la source a changé. Vous le faites avec cette méthode:

this.dataSource.data = yourDataSource;

où dataSource est le wrapper MatTableDataSource utilisé pour le tri et d'autres fonctionnalités.


0

Cela a fonctionné pour moi:

refreshTableSorce() {
    this.dataSource = new MatTableDataSource<Element>(this.newSource);
}

Ce n'est pas une solution idéale car il recrée la source pour la table. Et l'utiliser avec rationalisé / socket n'est pas efficace.
Maihan Nijat

0

Je pense que l' MatTableDataSourceobjet est en quelque sorte lié au tableau de données que vous passez au MatTableDataSourceconstructeur.

Par exemple:

dataTable: string[];
tableDS: MatTableDataSource<string>;

ngOnInit(){
   // here your pass dataTable to the dataSource
   this.tableDS = new MatTableDataSource(this.dataTable); 
}

Ainsi, lorsque vous devez modifier des données; modifier sur la liste d'origine dataTable, puis refléter le changement sur la table en appelant la _updateChangeSubscription()méthode sur tableDS.

Par exemple:

this.dataTable.push('testing');
this.tableDS._updateChangeSubscription();

Cela fonctionne avec moi via Angular 6.


4
Cette méthode est précédée d'un trait de soulignement _et vous l'appelez?
Stephane

0

Cela fonctionne pour moi:

dataSource = new MatTableDataSource<Dict>([]);
    public search() {
        let url = `${Constants.API.COMMON}/dicts?page=${this.page.number}&` + 
        (this.name == '' ? '' : `name_like=${this.name}`);
    this._http.get<Dict>(url).subscribe((data)=> {
    // this.dataSource = data['_embedded'].dicts;
    this.dataSource.data =  data['_embedded'].dicts;
    this.page = data['page'];
    this.resetSelection();
  });
}

Vous devez donc déclarer votre instance de source de données comme MatTableDataSource


0

J'ai fait quelques recherches supplémentaires et j'ai trouvé cet endroit pour me donner ce dont j'avais besoin - se sent propre et concerne les données de mise à jour lorsqu'elles sont actualisées à partir du serveur: https://blog.angular-university.io/angular-material-data-table/

La plupart des crédits à la page ci-dessus. Vous trouverez ci-dessous un exemple de la façon dont un sélecteur de tapis peut être utilisé pour mettre à jour une table de tapis liée à une source de données lors d'un changement de sélection. J'utilise Angular 7. Désolé pour être détaillé, essayant d'être complet mais concis - j'ai arraché autant de pièces inutiles que possible. Avec cela dans l'espoir d'aider quelqu'un d'autre à avancer plus vite!

organisation.model.ts:

export class Organization {
    id: number;
    name: String;
}

organization.service.ts:

import { Observable, empty } from 'rxjs';
import { of } from 'rxjs';

import { Organization } from './organization.model';

export class OrganizationService {
  getConstantOrganizations(filter: String): Observable<Organization[]> {
    if (filter === "All") {
      let Organizations: Organization[] = [
        { id: 1234, name: 'Some data' }
      ];
      return of(Organizations);
     } else {
       let Organizations: Organization[] = [
         { id: 5678, name: 'Some other data' }
       ];
     return of(Organizations);
  }

  // ...just a sample, other filterings would go here - and of course data instead fetched from server.
}

organizationdatasource.model.ts:

import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { Observable, BehaviorSubject, of } from 'rxjs';
import { catchError, finalize } from "rxjs/operators";

import { OrganizationService } from './organization.service';
import { Organization } from './organization.model';

export class OrganizationDataSource extends DataSource<Organization> {
  private organizationsSubject = new BehaviorSubject<Organization[]>([]);

  private loadingSubject = new BehaviorSubject<boolean>(false);

  public loading$ = this.loadingSubject.asObservable();

  constructor(private organizationService: OrganizationService, ) {
    super();
  }

  loadOrganizations(filter: String) {
    this.loadingSubject.next(true);

    return this.organizationService.getOrganizations(filter).pipe(
      catchError(() => of([])),
      finalize(() => this.loadingSubject.next(false))
    ).subscribe(organization => this.organizationsSubject.next(organization));
  }

  connect(collectionViewer: CollectionViewer): Observable<Organization[]> {
    return this.organizationsSubject.asObservable();
  }

  disconnect(collectionViewer: CollectionViewer): void {
    this.organizationsSubject.complete();
    this.loadingSubject.complete();
  }
}

organisations.component.html:

<div class="spinner-container" *ngIf="organizationDataSource.loading$ | async">
    <mat-spinner></mat-spinner>
</div>

<div>
  <form [formGroup]="formGroup">
    <mat-form-field fxAuto>
      <div fxLayout="row">
        <mat-select formControlName="organizationSelectionControl" (selectionChange)="updateOrganizationSelection()">
          <mat-option *ngFor="let organizationSelectionAlternative of organizationSelectionAlternatives"
            [value]="organizationSelectionAlternative">
            {{organizationSelectionAlternative.name}}
          </mat-option>
        </mat-select>
      </div>
    </mat-form-field>
  </form>
</div>

<mat-table fxLayout="column" [dataSource]="organizationDataSource">
  <ng-container matColumnDef="name">
    <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
    <mat-cell *matCellDef="let organization">{{organization.name}}</mat-cell>
  </ng-container>

  <ng-container matColumnDef="number">
    <mat-header-cell *matHeaderCellDef>Number</mat-header-cell>
    <mat-cell *matCellDef="let organization">{{organization.number}}</mat-cell>
  </ng-container>

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>

organisations.component.scss:

.spinner-container {
    height: 360px;
    width: 390px;
    position: fixed;
}

organization.component.ts:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { Observable } from 'rxjs';

import { OrganizationService } from './organization.service';
import { Organization } from './organization.model';
import { OrganizationDataSource } from './organizationdatasource.model';

@Component({
  selector: 'organizations',
  templateUrl: './organizations.component.html',
  styleUrls: ['./organizations.component.scss']
})
export class OrganizationsComponent implements OnInit {
  public displayedColumns: string[];
  public organizationDataSource: OrganizationDataSource;
  public formGroup: FormGroup;

  public organizationSelectionAlternatives = [{
    id: 1,
    name: 'All'
  }, {
    id: 2,
    name: 'With organization update requests'
  }, {
    id: 3,
    name: 'With contact update requests'
  }, {
    id: 4,
    name: 'With order requests'
  }]

  constructor(
    private formBuilder: FormBuilder,
    private organizationService: OrganizationService) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      'organizationSelectionControl': []
    })

    const toSelect = this.organizationSelectionAlternatives.find(c => c.id == 1);
    this.formGroup.get('organizationSelectionControl').setValue(toSelect);

    this.organizationDataSource = new OrganizationDataSource(this.organizationService);
    this.displayedColumns = ['name', 'number' ];
    this.updateOrganizationSelection();
  }

  updateOrganizationSelection() {
    this.organizationDataSource.loadOrganizations(this.formGroup.get('organizationSelectionControl').value.name);
  }
}

0

Après avoir lu Material Table ne mettant pas à jour la mise à jour des données post # 11638 Bug Report, j'ai trouvé que la meilleure (à lire, la solution la plus simple) était celle suggérée par le dernier commentateur 'shhdharmen' avec une suggestion d'utiliser un EventEmitter.

Cela implique quelques modifications simples de la classe de source de données générée

ie) ajoutez une nouvelle variable privée à votre classe de source de données

import { EventEmitter } from '@angular/core';
...
private tableDataUpdated = new EventEmitter<any>();

et là où je pousse de nouvelles données vers le tableau interne (this.data), j'émets un événement.

public addRow(row:myRowInterface) {
    this.data.push(row);
    this.tableDataUpdated.emit();
}

et enfin, changez le tableau 'dataMutation' dans la méthode 'connect' - comme suit

const dataMutations = [
    this.tableDataUpdated,
    this.paginator.page,
    this.sort.sortChange
];

0

// c'est la source de données
this.guests = [];

this.guests.push ({id: 1, nom: 'Ricardo'});

// actualise la source de données this.guests = Array.from (this.guest);


0
npm install @matheo/datasource

J'ai publié une bibliothèque destinée à devenir la source de données matérielle officielle à l'avenir, prenant en charge tout type de flux d'entrée (tri, pagination, filtres), et une configuration avec débogage pour voir comment cela fonctionne pendant que vous codez.

import { MatDataSourceModule } from '@matheo/datasource';

Vous pouvez trouver la démo StackBlitz et plus d'informations ici:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

Je serais ravi d'entendre votre avis et de soutenir vos cas d'utilisation si nécessaire.
Bon codage!


0

J'avais essayé ChangeDetectorRef, Subject and BehaviourSubject mais ce qui fonctionne pour moi

dataSource = [];
this.dataSource = [];
 setTimeout(() =>{
     this.dataSource = this.tableData[data];
 },200)

que se passe t-il ici? J'ai l'impression que des erreurs de dénomination variables ont été commises.
ChumiestBucket
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.