Używam tabeli mat do spisania treści w wybranych językach przez użytkowników. Mogą również dodawać nowe języki za pomocą panelu dialogowego. Po dodaniu języka i powrocie. Chcę, aby moje źródło danych odświeżyło się, aby pokazać wprowadzone przez nie zmiany.
Inicjalizuję magazyn danych, pobierając dane użytkownika z usługi i przekazując je do źródła danych w metodzie odświeżania.
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);
});
}
}
język-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
}
}
Próbowałem więc wywołać metodę odświeżania, w której ponownie pobieram użytkownika z zaplecza, a następnie ponownie inicjuję źródło danych. Jednak to nie działa, żadne zmiany nie występują.
Odpowiedzi:
Wywołaj wykrywanie zmiany, używając
ChangeDetectorRef
wrefresh()
metodzie tuż po otrzymaniu nowych danych, wstrzyknij ChangeDetectorRef do konstruktora i użyj funkcji detectionChanges w następujący sposób:źródło
Nie wiem, czy
ChangeDetectorRef
było wymagane przy tworzeniu pytania, ale teraz wystarczy:Przykład:
StackBlitz
źródło
MatTableDataSource.paginator
właściwości po zainicjowaniu widoku Paginatora. Zobacz opispaginator
nieruchomości tutaj: material.angular.io/components/table/api#MatTableDataSourceWięc dla mnie nikt nie dał dobrej odpowiedzi na napotkany problem, który jest prawie taki sam jak @Kay. U mnie chodzi o sortowanie, stół do sortowania nie zmienia się w macie. Mam na celu tę odpowiedź, ponieważ jest to jedyny temat, który znajduję, przeszukując google. Używam Angular 6.
Jak powiedziano tutaj :
Więc wystarczy wywołać renderRows () w metodzie refresh () , aby pojawiły się zmiany.
Zobacz tutaj integrację.
źródło
Ponieważ używasz
MatPaginator
, wystarczy wprowadzić jakąkolwiek zmianę w paginatorze, powoduje to ponowne załadowanie danych.Prosta sztuczka:
To aktualizuje rozmiar strony do aktualnego rozmiaru strony, więc w zasadzie nic się nie zmienia, z wyjątkiem
_emitPageEvent()
wywołania funkcji prywatnej , która powoduje ponowne załadowanie tabeli.źródło
_changePageSize()
nie jest publiczne, prawda? Czy jest to bezpieczne w użyciu? Więcej na stackoverflow.com/questions/59093781/…Dodaj tę linię poniżej akcji dodawania lub usuwania określonego wiersza.
źródło
Najlepszym sposobem na to jest dodanie dodatkowego obserwowalnego do implementacji źródła danych.
W metodzie connect powinieneś już używać
Observable.merge
do subskrybowania tablicy obserwabli, która zawiera paginator.page, sort.sortChange, itp. Możesz dodać do tego nowy temat i wywołać następny, gdy chcesz spowodować odświeżenie.coś takiego:
Następnie możesz zadzwonić,
recordChange$.next()
aby zainicjować odświeżanie.Oczywiście zawinąłbym wywołanie metodą refresh () i wywołałbym je z instancji źródła danych z komponentem i innymi odpowiednimi technikami.
źródło
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>'.
Możesz po prostu użyć funkcji łączenia źródła danych
jak tak. „dane” to nowe wartości dla bazy danych
źródło
Możesz łatwo zaktualizować dane tabeli za pomocą „concat”:
na przykład:
język.component.ts
language.component.html
Po zaktualizowaniu danych (język.component.ts):
Kiedy używasz "concat" kątowego, wykrywaj zmiany obiektu (this.teachDS) i nie musisz używać innej rzeczy.
PD: U mnie to działa w kątowej 6 i 7, nie próbowałem innej wersji.
źródło
W Angular 9 sekret jest
this.dataSource.data = this.dataSource.data;
Przykład:
źródło
Możesz także użyć metody renderRows ().
@ViewChild (MatTable, {static: false}) table: MatTable // inicjalizuj
następnie this.table.renderRows ();
w celach informacyjnych sprawdź to -: https://www.freakyjolly.com/angular-7-8-edit-add-delete-rows-in-material-table-with-using-dialogs-inline-row-operation/
źródło
Cóż, napotkałem podobny problem, w którym dodałem coś do źródła danych i nie ładuje się ponownie.
Najłatwiejszy sposób, jaki znalazłem, to po prostu ponowne przypisanie danych
źródło
Dobre rozwiązanie osiągnąłem przy użyciu dwóch zasobów:
odświeżenie źródła danych i paginatora:
gdzie na przykład dataSource jest zdefiniowana tutaj:
źródło
źródło
w moim przypadku (Angular 6+) odziedziczyłem
MatTableDataSource
po tworzenieMyDataSource
. Bez dzwonienia pothis.data = someArray
dane, gdzie nie są wyświetlane
klasa MyDataSource
źródło
Można to zrobić na dwa sposoby, ponieważ Angular Material jest niespójny i jest to bardzo słabo udokumentowane. Tabela materiałów kątowych nie zostanie zaktualizowana, gdy pojawi się nowy wiersz. Zaskakująco mówi się, że dzieje się tak z powodu problemów z wydajnością. Ale wygląda to bardziej na problem projektowy, nie mogą się zmienić. Należy oczekiwać, że tabela zostanie zaktualizowana, gdy pojawi się nowy wiersz. Jeśli to zachowanie nie powinno być domyślnie włączone, powinien być przełącznik, który je wyłącza.
W każdym razie nie możemy zmienić materiału kątowego. Ale w zasadzie możemy użyć bardzo słabo udokumentowanej metody, aby to zrobić:
Jeden - jeśli używasz tablicy bezpośrednio jako źródła:
gdzie tabela jest Widokiem dziecka tabeli mat
Po drugie - jeśli używasz sortowania i innych funkcji
table.renderRows () zaskakująco nie zadziała. Ponieważ stół mat jest tutaj niespójny. Musisz użyć hacka, aby powiedzieć, że źródło uległo zmianie. Robisz to tą metodą:
gdzie dataSource to opakowanie MatTableDataSource używane do sortowania i innych funkcji.
źródło
To zadziałało dla mnie:
źródło
Myślę, że
MatTableDataSource
obiekt jest w jakiś sposób powiązany z tablicą danych, którą przekazujesz doMatTableDataSource
konstruktora.Na przykład:
Tak więc, kiedy musisz zmienić dane; zmiana na oryginalnej liście,
dataTable
a następnie odzwierciedlenie zmiany w tabeli przez wywołanie_updateChangeSubscription()
metody ontableDS
.Na przykład:
To działa ze mną dzięki Angular 6.
źródło
_
i nazywasz ją?To działa dla mnie:
Dlatego należy zadeklarować instancję źródła danych jako
MatTableDataSource
źródło
Zrobiłem więcej badań i znalazłem to miejsce, aby dać mi to, czego potrzebowałem - czuję się czysty i odnosi się do aktualizacji danych po odświeżeniu z serwera: https://blog.angular-university.io/angular-material-data-table/
Większość kredytów na powyższej stronie. Poniżej znajduje się próbka, w jaki sposób selektor mat może być używany do aktualizowania tabeli mat powiązanej ze źródłem danych przy zmianie wyboru. Używam Angular 7. Przepraszam za to, że jestem obszerny, staram się być kompletny, ale zwięzły - wyrwałem jak najwięcej niepotrzebnych części. Mając nadzieję, że pomoże komuś przyspieszyć postęp!
organization.model.ts:
organization.service.ts:
organizationdatasource.model.ts:
Organisations.component.html:
Organisations.component.scss:
organizacja.component.ts:
źródło
Po przeczytaniu tabeli materiałów nie aktualizowano danych po aktualizacji # 11638 Raport o błędzie , znalazłem najlepsze (przeczytaj, najłatwiejsze rozwiązanie), zgodnie z sugestią ostatniego komentatora „shhdharmen” z sugestią użycia EventEmittera.
Wymaga to kilku prostych zmian w wygenerowanej klasie źródła danych
ie) dodaj nową zmienną prywatną do klasy źródła danych
i gdzie wypycham nowe dane do wewnętrznej tablicy (this.data), emituję zdarzenie.
i na koniec zmień tablicę „dataMutation” w metodzie „connect” - w następujący sposób
źródło
// to jest źródło danych
this.guests = [];
this.guests.push ({id: 1, nazwa: „Ricardo”});
// odśwież źródło danych this.guests = Array.from (this.guest);
źródło
Wydałem bibliotekę, która ma być w przyszłości oficjalnym Material DataSource, obsługując wszelkiego rodzaju strumienie wejściowe (sortowanie, paginację, filtry) i konfigurację z debugowaniem, aby zobaczyć, jak to działa podczas kodowania.
Możesz znaleźć demo StackBlitz i dalsze informacje tutaj:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6
Chętnie wysłucham Twojej opinii i w razie potrzeby wesprzemy Twoje przypadki użycia.
Miłego kodowania!
źródło
Próbowałem ChangeDetectorRef, Subject i BehaviourSubject, ale to, co działa dla mnie
źródło