Angular + Material - Jak odświeżyć źródło danych (mat-table)

122

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ą.

Okej
źródło
1
Jeśli chcesz wywołać zmianę „ze źródła danych”, zajrzyj na stackoverflow.com/questions/47897694/ ...
Yennefer
W takim przypadku można użyć emiterów zdarzeń. stackoverflow.com/a/44858648/8300620
Rohit Parte

Odpowiedzi:

58

Wywołaj wykrywanie zmiany, używając ChangeDetectorRefw refresh()metodzie tuż po otrzymaniu nowych danych, wstrzyknij ChangeDetectorRef do konstruktora i użyj funkcji detectionChanges w następujący sposób:

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();
    });
  }
}
HDJEMAI
źródło
9
To wydaje się działać, czy to właściwy sposób? Wydaje się trochę hacky ...
Kay,
Jakie są inne sposoby? Czy możesz podać przykłady w swoim rozwiązaniu, aby uzyskać pełną odpowiedź?
Kay
89

Nie wiem, czy ChangeDetectorRefbyło wymagane przy tworzeniu pytania, ale teraz wystarczy:

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

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

Przykład:
StackBlitz

Martin Schneider
źródło
4
Chociaż to rozwiązanie w rzeczywistości działa, psuje paginator materiałów, jeśli element zostanie dodany w innym miejscu niż pierwsza strona wyników. Rozumiem, że to wykracza poza zakres tego pytania, ale skoro oba są ze sobą powiązane, czy zdarza się, że masz szybkie rozwiązanie tego problemu, które możesz dodać do swojej odpowiedzi?
Knight
5
@Knight Myślę, że musisz przypisać Paginator do MatTableDataSource.paginatorwłaściwości po zainicjowaniu widoku Paginatora. Zobacz opis paginatornieruchomości tutaj: material.angular.io/components/table/api#MatTableDataSource
Martin Schneider
Dobre odniesienie. Nie zauważyłem tego wcześniej w dokumentach. Dzięki!
Knight
2
@ MA-Maddin czy możesz podać bardziej szczegółowe informacje, jak to zrobić? przykład?
Nathanphan
@Nathanphan spóźnił się, ale dodał przykład;)
Martin Schneider
46

Wię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 :

Ponieważ tabela jest optymalizowana pod kątem wydajności, nie będzie automatycznie sprawdzać zmian w tablicy danych. Zamiast tego, gdy obiekty są dodawane, usuwane lub przenoszone w tablicy danych, można wyzwolić aktualizację renderowanych wierszy tabeli, wywołując jej metodę renderRows ().

Więc wystarczy wywołać renderRows () w metodzie refresh () , aby pojawiły się zmiany.

Zobacz tutaj integrację.

4x10m
źródło
1
Jeśli źródło danych tabeli zostało zmienione na kliencie, prawdopodobnie szukasz tej odpowiedzi. Działa świetnie!
Alvin Saldanha,
To jest poprawna odpowiedź od materiału kątowego 8
Tom
Dziękuję Ci. Ale z którego obiektu powinienem wywołać metodę „renderRows ()”? Czy jest w „this.datasource”?
WitnessTruth
19

Ponieważ używasz MatPaginator, wystarczy wprowadzić jakąkolwiek zmianę w paginatorze, powoduje to ponowne załadowanie danych.

Prosta sztuczka:

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

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.

takeshin
źródło
Wypróbowałem twój kod i nie działa (bez efektu). Jednak nextPage, a następnie previousPage znowu działa, ale nie jest rozwiązaniem.
Ahmed Hasn.
_changePageSize()nie jest publiczne, prawda? Czy jest to bezpieczne w użyciu? Więcej na stackoverflow.com/questions/59093781/…
Jones
9
this.dataSource = new MatTableDataSource<Element>(this.elements);

Dodaj tę linię poniżej akcji dodawania lub usuwania określonego wiersza.

refresh() {
  this.authService.getAuthenticatedUser().subscribe((res) => {
    this.user = new MatTableDataSource<Element>(res);   
  });
}
Pooja Paigude
źródło
co to jest. elementy
parvat
8

Najlepszym sposobem na to jest dodanie dodatkowego obserwowalnego do implementacji źródła danych.

W metodzie connect powinieneś już używać Observable.mergedo 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:

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
    }
}

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.

jogi
źródło
Ta metoda może być właściwą drogą. U mnie działa dobrze
Manu
jak to zaimplementować, gdy chcę rozszerzyć MatTableDataSource? Kiedy wypróbowuję Twój przykład kodu, pojawia się błądProperty '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 typ MatTableDataSource implementuje metodę connect z innym zwracanym typem. Używa BehaviorSubject <t []>, co oznacza, że ​​wystarczy zmienić przykład, aby zwrócić to zamiast Observable. Nadal powinieneś być w stanie korzystać z DataSource, ale jeśli musisz użyć MatTableDataSource, zwróć BehaviorSubject, który jest subskrybowany do twojego obserowalnego, zakładając, że masz taki, od którego możesz zacząć. Mam nadzieję, że to pomoże. Możesz odnieść się do źródła MatTableDataSource, aby uzyskać dokładną składnię nowego typu źródła danych: github.com/angular/material2/blob/master/src/lib/table/ ...
jogi
7

Możesz po prostu użyć funkcji łączenia źródła danych

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

jak tak. „dane” to nowe wartości dla bazy danych

cozmik05
źródło
Miał potencjał, ale nie wydaje się działać. Jeśli po tym uzyskasz dostęp do this.datasource.data, nie zostanie zaktualizowany.
Rui Marques,
4

Możesz łatwo zaktualizować dane tabeli za pomocą „concat”:

na przykład:

język.component.ts

teachDS: any[] = [];

language.component.html

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

Po zaktualizowaniu danych (język.component.ts):

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

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.

Mayra Rodriguez
źródło
2
Tak, u mnie działa, jest problem z referencją i wartością var, wykrywanie zmian nie widzi nowych zmian, do tego trzeba je zaktualizować.
Mayra Rodriguez
Może to zadziałać, jeśli dataSource jest tylko tablicą, ale nie, gdy dataSource jest obiektem MatTableDataSource.
Rui Marques
4

W Angular 9 sekret jest this.dataSource.data = this.dataSource.data;

Przykład:

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);
}
Nicolas
źródło
3

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

let dataSource = ['a','b','c']
dataSource.push('d')
let cloned = dataSource.slice()
// OR IN ES6 // let cloned = [...dataSource]
dataSource = cloned
Mordy Stern
źródło
Idealny!! To wokrs !! Dzięki :)
Nicolas
2

Dobre rozwiązanie osiągnąłem przy użyciu dwóch zasobów:

odświeżenie źródła danych i paginatora:

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

gdzie na przykład dataSource jest zdefiniowana tutaj:

    users: User[];
    ...
    dataSource = new MatTableDataSource(this.users);
    ...
    this.dataSource.paginator = this.paginator;
    ...
danilo
źródło
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);   
    });
  }
}
Machhindra Neupane
źródło
8
Dodaj wyjaśnienie do odpowiedzi, samo wysłanie kodu nie jest zbyt pomocne i może spowodować usunięcie odpowiedzi.
TJ Wolschon
1

w moim przypadku (Angular 6+) odziedziczyłem MatTableDataSourcepo tworzenie MyDataSource. Bez dzwonienia pothis.data = someArray

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

dane, gdzie nie są wyświetlane

klasa 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 
Pipo
źródło
1

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:

call table.renderRows()

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ą:

this.dataSource.data = yourDataSource;

gdzie dataSource to opakowanie MatTableDataSource używane do sortowania i innych funkcji.

Tomasz Smykowski
źródło
0

To zadziałało dla mnie:

refreshTableSorce() {
    this.dataSource = new MatTableDataSource<Element>(this.newSource);
}
Cristian Hernandez
źródło
Nie jest to idealne rozwiązanie, ponieważ odtwarza źródło dla tabeli, a używanie tego z opływowym / gniazdem nie jest wydajne.
Maihan Nijat
0

Myślę, że MatTableDataSourceobiekt jest w jakiś sposób powiązany z tablicą danych, którą przekazujesz do MatTableDataSourcekonstruktora.

Na przykład:

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

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

Tak więc, kiedy musisz zmienić dane; zmiana na oryginalnej liście, dataTablea następnie odzwierciedlenie zmiany w tabeli przez wywołanie _updateChangeSubscription()metody on tableDS.

Na przykład:

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

To działa ze mną dzięki Angular 6.

nimeresam
źródło
4
Ta metoda jest poprzedzona podkreśleniem _i nazywasz ją?
Stephane
0

To działa dla mnie:

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();
  });
}

Dlatego należy zadeklarować instancję źródła danych jako MatTableDataSource

Tiny King
źródło
0

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:

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;
}

organizacja.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);
  }
}
Henrik
źródło
0

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

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

i gdzie wypycham nowe dane do wewnętrznej tablicy (this.data), emituję zdarzenie.

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

i na koniec zmień tablicę „dataMutation” w metodzie „connect” - w następujący sposób

const dataMutations = [
    this.tableDataUpdated,
    this.paginator.page,
    this.sort.sortChange
];
Gav_at_HRSTS
źródło
0

// 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);

Igor Faoro
źródło
0
npm install @matheo/datasource

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.

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

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!

Mateo Tibaquira
źródło
0

Próbowałem ChangeDetectorRef, Subject i BehaviourSubject, ale to, co działa dla mnie

dataSource = [];
this.dataSource = [];
 setTimeout(() =>{
     this.dataSource = this.tableData[data];
 },200)
Vishesh Mishra
źródło
co tu się dzieje? Wydaje mi się, że popełniono błędy w nazewnictwie zmiennych.
ChumiestBucket