Ich verwende eine Mat-Tabelle, um den Inhalt der vom Benutzer ausgewählten Sprachen aufzulisten. Sie können auch neue Sprachen über das Dialogfeld hinzufügen. Nachdem sie eine Sprache hinzugefügt und zurückgekehrt waren. Ich möchte, dass meine Datenquelle aktualisiert wird, um die vorgenommenen Änderungen anzuzeigen.
Ich initialisiere den Datenspeicher, indem ich Benutzerdaten von einem Dienst abrufe und diese in der Aktualisierungsmethode an eine Datenquelle übergebe.
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);
});
}
}
language-data-source.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
}
}
Daher habe ich versucht, eine Aktualisierungsmethode aufzurufen, bei der der Benutzer erneut aus dem Backend abgerufen und dann die Datenquelle neu initialisiert wird. Dies funktioniert jedoch nicht, es treten keine Änderungen auf.
Antworten:
Lösen Sie eine Änderungserkennung aus, indem Sie
ChangeDetectorRef
dierefresh()
Methode direkt nach dem Empfang der neuen Daten verwenden, ChangeDetectorRef in den Konstruktor einfügen und detectChanges wie folgt verwenden :quelle
Ich weiß nicht, ob das
ChangeDetectorRef
erforderlich war, als die Frage erstellt wurde, aber jetzt ist dies genug:Beispiel:
StackBlitz
quelle
MatTableDataSource.paginator
Eigenschaft zuweisen, nachdem die Ansicht des Paginators initialisiert wurde. Siehe die Beschreibung derpaginator
Eigenschaft hier: material.angular.io/components/table/api#MatTableDataSourceFür mich gab niemand die gute Antwort auf das Problem, das ich getroffen habe und das fast das gleiche ist wie @Kay. Für mich geht es um das Sortieren, Sortiertabellen treten keine Änderungen in der Matte auf. Ich beabsichtige diese Antwort, da es das einzige Thema ist, das ich bei der Suche in Google finde. Ich benutze Angular 6.
Wie hier gesagt :
So müssen Sie nur noch rufen renderRows () in der refresh () Methode , um Ihre Änderungen angezeigt werden.
Siehe hier für die Integration.
quelle
Da Sie verwenden
MatPaginator
, müssen Sie nur Änderungen am Paginator vornehmen. Dies löst ein erneutes Laden der Daten aus.Einfacher Trick:
Dadurch wird die Seitengröße auf die aktuelle Seitengröße aktualisiert, sodass sich im Grunde nichts ändert, außer dass auch die private
_emitPageEvent()
Funktion aufgerufen wird, wodurch das erneute Laden der Tabelle ausgelöst wird.quelle
_changePageSize()
ist nicht öffentlich richtig? Ist es sicher zu bedienen? Mehr auf stackoverflow.com/questions/59093781/…Fügen Sie diese Zeile unterhalb Ihrer Aktion zum Hinzufügen oder Löschen der jeweiligen Zeile hinzu.
quelle
Der beste Weg, dies zu tun, besteht darin, Ihrer Datenquellenimplementierung ein zusätzliches Observable hinzuzufügen.
In der Connect-Methode sollten Sie bereits
Observable.merge
ein Array von Observables abonnieren, zu denen paginator.page, sort.sortChange usw. gehören. Sie können diesem einen neuen Betreff hinzufügen und ihn als Nächstes aufrufen, wenn Sie eine Aktualisierung veranlassen müssen.etwas wie das:
Und dann können Sie anrufen
recordChange$.next()
, um eine Aktualisierung zu starten.Natürlich würde ich den Aufruf in eine refresh () -Methode einschließen und ihn von der Datenquelleninstanz w / in der Komponente und anderen geeigneten Techniken abrufen.
quelle
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>'.
Sie können einfach die Datenquellen-Verbindungsfunktion verwenden
wie so. 'Daten' sind die neuen Werte für die Datentabelle
quelle
Sie können die Daten der Tabelle einfach mit "concat" aktualisieren:
beispielsweise:
language.component.ts
language.component.html
Und wenn Sie die Daten aktualisieren (language.component.ts):
Wenn Sie "concat" eckig verwenden, erkennen Sie die Änderungen des Objekts (this.teachDS) und Sie müssen nichts anderes verwenden.
PD: Es funktioniert für mich in Winkel 6 und 7, ich habe keine andere Version ausprobiert.
quelle
Sie können auch die renderRows () -Methode verwenden.
@ ViewChild (MatTable, {static: false}) Tabelle: MatTable // initialisieren
dann this.table.renderRows ();
Als Referenz überprüfen Sie dies -: https://www.freakyjolly.com/angular-7-8-edit-add-delete-rows-in-material-table-with-using-dialogs-inline-row-operation/
quelle
Nun, ich bin auf ein ähnliches Problem gestoßen, bei dem ich der Datenquelle etwas hinzugefügt habe und es nicht neu geladen wird.
Der einfachste Weg, den ich gefunden habe, war einfach, die Daten neu zuzuweisen
quelle
In Angular 9 ist das Geheimnis
this.dataSource.data = this.dataSource.data;
Beispiel:
quelle
Ich habe mit zwei Ressourcen eine gute Lösung erzielt:
Aktualisieren von dataSource und paginator:
Hier wird beispielsweise dataSource definiert:
quelle
quelle
In meinem Fall (Angular 6+) habe ich geerbt
MatTableDataSource
, um zu erstellenMyDataSource
. Ohne Aufruf nachthis.data = someArray
Daten wurden nicht angezeigt
Klasse MyDataSource
quelle
Es gibt zwei Möglichkeiten, dies zu tun, da Angular Material inkonsistent ist und dies sehr schlecht dokumentiert ist. Die Winkelmaterialtabelle wird nicht aktualisiert, wenn eine neue Zeile eintrifft. Überraschenderweise wird gesagt, dass es an Leistungsproblemen liegt. Aber es sieht eher nach einem Designproblem aus, sie können sich nicht ändern. Es sollte erwartet werden, dass die Tabelle aktualisiert wird, wenn eine neue Zeile auftritt. Wenn dieses Verhalten nicht standardmäßig aktiviert sein soll, sollte es einen Schalter zum Ausschalten geben.
Auf jeden Fall können wir Angular Material nicht ändern. Grundsätzlich können wir jedoch eine sehr schlecht dokumentierte Methode verwenden:
Eins - wenn Sie ein Array direkt als Quelle verwenden:
Dabei ist table ViewChild der Mat-Tabelle
Zweitens - wenn Sie Sortierung und andere Funktionen verwenden
table.renderRows () funktioniert überraschenderweise nicht. Weil mat-table hier inkonsistent ist. Sie müssen einen Hack verwenden, um die geänderte Quelle mitzuteilen. Sie machen es mit dieser Methode:
Dabei ist dataSource der MatTableDataSource-Wrapper, der zum Sortieren und für andere Funktionen verwendet wird.
quelle
Das hat bei mir funktioniert:
quelle
Ich denke, das
MatTableDataSource
Objekt ist in irgendeiner Weise mit dem Datenarray verknüpft, das Sie an denMatTableDataSource
Konstruktor übergeben.Zum Beispiel:
Also, wenn Sie Daten ändern müssen; Ändern Sie in der ursprünglichen Liste
dataTable
und spiegeln Sie dann die Änderung in der Tabelle durch die_updateChangeSubscription()
Aufrufmethode eintableDS
.Zum Beispiel:
Das ist Arbeit mit mir durch Angular 6.
quelle
_
und Sie nennen es?Das funktioniert bei mir:
Daher sollten Sie Ihre Datenquelleninstanz als deklarieren
MatTableDataSource
quelle
Ich habe weitere Nachforschungen angestellt und diesen Ort gefunden, um mir das zu geben, was ich brauchte - fühlt sich sauber an und bezieht sich auf Aktualisierungsdaten, wenn diese vom Server aktualisiert werden: https://blog.angular-university.io/angular-material-data-table/
Die meisten Credits auf der obigen Seite. Im Folgenden finden Sie ein Beispiel dafür, wie ein Mattenselektor verwendet werden kann, um eine Mattentabelle zu aktualisieren, die bei Änderung der Auswahl an eine Datenquelle gebunden ist. Ich verwende Angular 7. Es tut mir leid, dass ich umfangreich bin und versuche, vollständig, aber präzise zu sein. Ich habe so viele nicht benötigte Teile wie möglich herausgerissen. In der Hoffnung, jemand anderem zu helfen, schneller voranzukommen!
organisation.model.ts:
organisation.service.ts:
organisationdatasource.model.ts:
organisations.component.html:
organisations.component.scss:
organisation.component.ts:
quelle
Nachdem ich die Materialtabelle gelesen hatte, die nach der Aktualisierung der Daten nicht aktualisiert wurde # 11638 Fehlerbericht Ich fand die beste (gelesene, einfachste Lösung), wie vom letzten Kommentator 'shhdharmen' mit einem Vorschlag zur Verwendung eines EventEmitter vorgeschlagen.
Dies beinhaltet einige einfache Änderungen an der generierten Datenquellenklasse
dh) fügen Sie Ihrer Datenquellenklasse eine neue private Variable hinzu
und wo ich neue Daten in das interne Array (this.data) schiebe, gebe ich ein Ereignis aus.
und schließlich ändern Sie das Array 'dataMutation' in der Methode 'connect' wie folgt
quelle
// das ist die dataSource
this.guests = [];
this.guests.push ({id: 1, name: 'Ricardo'});
// aktualisiere die dataSource this.guests = Array.from (this.guest);
quelle
Ich habe eine Bibliothek veröffentlicht, die in Zukunft die offizielle Material DataSource sein soll und jede Art von Eingabestreams (Sortieren, Paginieren, Filtern) und einige Konfigurationen mit Debugging unterstützt, um zu sehen, wie es beim Codieren funktioniert.
Die StackBlitz-Demo und weitere Informationen finden Sie hier:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6
Ich würde mich freuen, Ihre Meinung zu hören und Ihre Anwendungsfälle bei Bedarf zu unterstützen.
Viel Spaß beim Codieren!
quelle
Ich hatte ChangeDetectorRef, Subject und BehaviourSubject ausprobiert, aber was funktioniert für mich?
quelle