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.
Réponses:
Déclenchez une détection de changement en utilisant
ChangeDetectorRef
dans larefresh()
méthode juste après avoir reçu les nouvelles données, injectez ChangeDetectorRef dans le constructeur et utilisez detectChanges comme ceci:la source
Je ne sais pas si le
ChangeDetectorRef
était requis lors de la création de la question, mais maintenant cela suffit:Exemple:
StackBlitz
la source
MatTableDataSource.paginator
propriété une fois que la vue du Paginator a été initialisée. Voir la description de lapaginator
propriété ici: material.angular.io/components/table/api#MatTableDataSourceDonc 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 :
Il vous suffit donc d'appeler renderRows () dans votre méthode refresh () pour que vos modifications apparaissent.
Voir ici pour l'intégration.
la source
Puisque vous utilisez
MatPaginator
, il vous suffit de modifier le paginateur, cela déclenche le rechargement des données.Astuce simple:
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.la source
_changePageSize()
n'est-ce pas public? Est-il sûr à utiliser? Plus d'informations sur stackoverflow.com/questions/59093781/…Ajoutez cette ligne sous votre action d'ajout ou de suppression de la ligne particulière.
la source
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.merge
pour 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:
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.
la source
Property '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>'.
Vous pouvez simplement utiliser la fonction de connexion à la source de données
ainsi. 'data' étant les nouvelles valeurs de la table de données
la source
Vous pouvez facilement mettre à jour les données de la table en utilisant "concat":
par exemple:
language.component.ts
language.component.html
Et, lorsque vous mettez à jour les données (language.component.ts):
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.
la source
Vous pouvez également utiliser la méthode renderRows ().
@ViewChild (MatTable, {static: false}) table: MatTable // initialiser
puis this.table.renderRows ();
pour référence, consultez ceci -: https://www.freakyjolly.com/angular-7-8-edit-add-delete-rows-in-material-table-with-using-dialogs-inline-row-operation/
la source
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
la source
Dans Angular 9, le secret est
this.dataSource.data = this.dataSource.data;
Exemple:
la source
J'ai réalisé une bonne solution en utilisant deux ressources:
actualisation à la fois de la source de données et du paginateur:
où par exemple dataSource est défini ici:
la source
la source
dans mon cas (Angular 6+), j'ai hérité de
MatTableDataSource
créerMyDataSource
. Sans appeler aprèsthis.data = someArray
les données ne sont pas affichées
classe MyDataSource
la source
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:
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:
où dataSource est le wrapper MatTableDataSource utilisé pour le tri et d'autres fonctionnalités.
la source
Cela a fonctionné pour moi:
la source
Je pense que l'
MatTableDataSource
objet est en quelque sorte lié au tableau de données que vous passez auMatTableDataSource
constructeur.Par exemple:
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 surtableDS
.Par exemple:
Cela fonctionne avec moi via Angular 6.
la source
_
et vous l'appelez?Cela fonctionne pour moi:
Vous devez donc déclarer votre instance de source de données comme
MatTableDataSource
la source
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:
organization.service.ts:
organizationdatasource.model.ts:
organisations.component.html:
organisations.component.scss:
organization.component.ts:
la source
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
et là où je pousse de nouvelles données vers le tableau interne (this.data), j'émets un événement.
et enfin, changez le tableau 'dataMutation' dans la méthode 'connect' - comme suit
la source
// 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);
la source
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.
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!
la source
J'avais essayé ChangeDetectorRef, Subject and BehaviourSubject mais ce qui fonctionne pour moi
la source