Angular + Material - Cara menyegarkan sumber data (mat-table)

120

Saya menggunakan mat-table untuk membuat daftar konten bahasa yang dipilih pengguna. Mereka juga dapat menambahkan bahasa baru menggunakan panel dialog. Setelah mereka menambahkan bahasa dan kembali lagi. Saya ingin sumber data saya diperbarui untuk menunjukkan perubahan yang mereka buat.

Saya menginisialisasi datastore dengan mendapatkan data pengguna dari layanan dan meneruskannya ke sumber data dalam metode refresh.

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

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

}

Jadi saya telah mencoba memanggil metode penyegaran di mana saya mendapatkan pengguna dari backend lagi dan kemudian saya menginisialisasi ulang sumber data. Namun ini tidak berhasil, tidak ada perubahan yang terjadi.

Kay
sumber
1
Jika Anda ingin memicu perubahan "dari sumber data", lihat stackoverflow.com/questions/47897694/…
Yennefer
Pengemisi acara dapat digunakan dalam kasus ini. stackoverflow.com/a/44858648/8300620
Rohit Parte

Jawaban:

58

Pemicu deteksi perubahan dengan menggunakan ChangeDetectorRefdalam refresh()metode hanya setelah menerima data baru, menyuntikkan ChangeDetectorRef dalam konstruktor dan penggunaan detectChanges seperti ini:

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
sumber
9
Tampaknya berhasil, apakah ini cara yang tepat untuk melakukannya? Sepertinya agak hacky ...
Kay
Apa cara lainnya? Bisakah Anda memberikan contoh dalam solusi Anda untuk jawaban lengkap?
Kay
88

Saya tidak tahu apakah ChangeDetectorRefdiperlukan saat pertanyaan dibuat, tetapi sekarang ini sudah cukup:

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

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

Contoh:
StackBlitz

Martin Schneider
sumber
4
Meskipun solusi ini sebenarnya berfungsi, solusi ini mengacaukan paginator material jika elemen ditambahkan di tempat lain selain halaman pertama hasil. Saya memahami bahwa itu berada di luar cakupan pertanyaan ini tetapi karena keduanya terkait, apakah Anda kebetulan memiliki solusi cepat untuk masalah itu yang dapat Anda tambahkan ke jawaban Anda?
Knight
5
@Knight Saya rasa Anda harus menetapkan Paginator ke MatTableDataSource.paginatorproperti setelah tampilan Paginator diinisialisasi. Lihat deskripsi paginatorproperti di sini: material.angular.io/components/table/api#MatTableDataSource
Martin Schneider
Referensi yang bagus. Saya belum pernah melihatnya di dokumen sebelumnya. Terima kasih!
Knight
2
@ MA-Maddin dapatkah Anda lebih spesifik tentang cara melakukannya? contoh?
Nathanphan
@Nathanphan terlambat, tetapi menambahkan contoh;)
Martin Schneider
46

Jadi bagi saya, tidak ada yang memberikan jawaban yang baik untuk masalah yang saya temui yang hampir sama dengan @Kay. Bagi saya ini soal sortir, tidak terjadi perubahan pada meja sortir pada matras. Saya bertujuan jawaban ini karena ini satu-satunya topik yang saya temukan dengan mencari di google. Saya menggunakan Angular 6.

Seperti yang dikatakan di sini :

Karena tabel mengoptimalkan kinerja, tabel tidak akan secara otomatis memeriksa perubahan pada larik data. Sebaliknya, ketika objek ditambahkan, dihapus, atau dipindahkan pada larik data, Anda bisa memicu pembaruan ke baris yang dirender tabel dengan memanggil metode renderRows ().

Jadi Anda hanya perlu memanggil renderRows () dalam metode refresh () untuk membuat perubahan Anda muncul.

Lihat di sini untuk integrasi.

4x10m
sumber
1
Jika sumber data tabel diubah pada klien, jawaban ini adalah yang mungkin Anda cari. Bekerja dengan baik!
Alvin Saldanha
Ini adalah jawaban yang benar untuk bahan sudut 8
Tom
Terima kasih. Tapi dari objek mana saya harus memanggil "renderRows ()"? Apakah ada di 'this.datasource'?
WitnessTruth
19

Karena Anda menggunakan MatPaginator, Anda hanya perlu melakukan perubahan apa pun ke paginator, ini memicu pemuatan ulang data.

Trik sederhana:

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

Ini memperbarui ukuran halaman ke ukuran halaman saat ini, jadi pada dasarnya tidak ada yang berubah, kecuali _emitPageEvent()fungsi pribadi dipanggil juga, memicu pemuatan ulang tabel.

takeshin
sumber
Saya mencoba kode Anda dan tidak berhasil (tidak berpengaruh). Namun nextPage dan kemudian PreviousPage lagi berfungsi, tetapi tidak ada solusi.
Ahmed Hasn.
_changePageSize()bukankah publik benar? Apakah ini aman untuk digunakan? Selengkapnya tentang stackoverflow.com/questions/59093781/…
Jones
9
this.dataSource = new MatTableDataSource<Element>(this.elements);

Tambahkan baris ini di bawah tindakan Anda menambah atau menghapus baris tertentu.

refresh() {
  this.authService.getAuthenticatedUser().subscribe((res) => {
    this.user = new MatTableDataSource<Element>(res);   
  });
}
Pooja Paigude
sumber
elemen apa ini
parvat
8

Cara terbaik untuk melakukannya adalah dengan menambahkan observasi tambahan ke penerapan Sumber Data Anda.

Dalam metode hubungkan, Anda seharusnya sudah menggunakan Observable.mergeuntuk berlangganan larik observabel yang menyertakan paginator.page, sort.sortChange, dll. Anda dapat menambahkan subjek baru ke ini dan memanggilnya berikutnya saat Anda perlu membuat penyegaran.

sesuatu seperti ini:

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

Dan kemudian Anda dapat menelepon recordChange$.next()untuk memulai penyegaran.

Secara alami saya akan membungkus panggilan dalam metode refresh () dan membatalkannya dari contoh sumber data w / dalam komponen, dan teknik yang tepat lainnya.

jogi
sumber
Cara ini mungkin cara yang benar. Ini berfungsi dengan baik untuk saya
Manu
bagaimana cara menerapkan ini ketika saya ingin memperluas MatTableDataSource? Ketika saya mencoba contoh kode Anda, saya mendapatkan kesalahanProperty '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 tipe MatTableDataSource mengimplementasikan metode koneksi dengan tipe pengembalian yang berbeda. Ini menggunakan BehaviorSubject <t []> yang berarti Anda hanya perlu mengubah contoh untuk mengembalikan ini alih-alih Observable. Anda masih harus dapat menggunakan DataSource tetapi jika Anda harus menggunakan MatTableDataSource maka kembalikan BehaviorSubject yang berlangganan ke observable Anda, dengan asumsi Anda memiliki satu untuk memulai. Semoga membantu. Anda dapat merujuk ke sumber MatTableDataSource untuk sintaks yang tepat dari jenis sumber data baru: github.com/angular/material2/blob/master/src/lib/table/…
jogi
7

Anda cukup menggunakan fungsi menghubungkan sumber data

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

seperti itu. 'data' menjadi nilai baru untuk datatable

cozmik05
sumber
Memiliki potensi tetapi sepertinya tidak berhasil. Jika setelah itu Anda mengakses this.datasource.data, Ini tidak diperbarui.
Rui Marques
4

Anda dapat dengan mudah memperbarui data tabel menggunakan "concat":

sebagai contoh:

language.component.ts

teachDS: any[] = [];

language.component.html

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

Dan, saat Anda memperbarui data (language.component.ts):

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

Saat Anda menggunakan "concat" angular mendeteksi perubahan objek (this.teachDS) dan Anda tidak perlu menggunakan hal lain.

PD: Ini bekerja untuk saya di sudut 6 dan 7, saya tidak mencoba versi lain.

Mayra Rodriguez
sumber
2
Ya, Ini berfungsi untuk saya, ini masalah tentang referensi dan nilai var, deteksi perubahan tidak melihat perubahan baru, untuk itu Anda perlu memperbaruinya.
Mayra Rodriguez
Ini mungkin berfungsi jika dataSource hanyalah sebuah array tetapi tidak jika dataSource adalah objek MatTableDataSource.
Rui Marques
3

Nah, saya mengalami masalah serupa di mana saya menambahkan sesuatu ke sumber data dan tidak memuat ulang.

Cara termudah yang saya temukan adalah dengan menetapkan ulang data

let dataSource = ['a','b','c']
dataSource.push('d')
let cloned = dataSource.slice()
// OR IN ES6 // let cloned = [...dataSource]
dataSource = cloned
Mordy Stern
sumber
Sempurna!! Ini wokrs !! Terima kasih :)
Nicolas
3

Di Angular 9, rahasianya adalah this.dataSource.data = this.dataSource.data;

Contoh:

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
sumber
2

Saya mencapai solusi yang baik dengan menggunakan dua sumber:

menyegarkan dataSource dan paginator:

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

di mana misalnya dataSource didefinisikan di sini:

    users: User[];
    ...
    dataSource = new MatTableDataSource(this.users);
    ...
    this.dataSource.paginator = this.paginator;
    ...
danilo
sumber
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
sumber
8
Harap tambahkan penjelasan pada jawaban Anda, kode posting saja tidak terlalu membantu dan dapat mengakibatkan jawaban Anda dihapus.
TJ Wolschon
1

dalam kasus saya (Angular 6+), saya mewarisi dari MatTableDataSourceuntuk membuat MyDataSource. Tanpa menelepon setelahnyathis.data = someArray

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

data di mana tidak ditampilkan

kelas 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
sumber
1

Ada dua cara untuk melakukannya karena Angular Material tidak konsisten, dan ini didokumentasikan dengan sangat buruk. Tabel material sudut tidak akan diperbarui ketika baris baru akan tiba. Anehnya, hal itu dikatakan karena masalah kinerja. Tapi sepertinya masalah desain, mereka tidak bisa berubah. Ini diharapkan untuk tabel untuk memperbarui ketika baris baru terjadi. Jika perilaku ini tidak boleh diaktifkan secara default, harus ada tombol untuk menonaktifkannya.

Bagaimanapun, kami tidak dapat mengubah Material Angular. Tetapi pada dasarnya kita dapat menggunakan metode yang terdokumentasi dengan sangat buruk untuk melakukannya:

Satu - jika Anda menggunakan array secara langsung sebagai sumber:

call table.renderRows()

di mana tabel adalah ViewChild dari mat-table

Kedua - jika Anda menggunakan penyortiran dan fitur lainnya

table.renderRows () secara mengejutkan tidak akan berfungsi. Karena mat-table tidak konsisten di sini. Anda perlu menggunakan retasan untuk memberi tahu sumbernya berubah. Anda melakukannya dengan metode ini:

this.dataSource.data = yourDataSource;

di mana dataSource adalah pembungkus MatTableDataSource yang digunakan untuk pengurutan dan fitur lainnya.

Tomasz Smykowski
sumber
0

Ini berhasil untuk saya:

refreshTableSorce() {
    this.dataSource = new MatTableDataSource<Element>(this.newSource);
}
Cristian Hernandez
sumber
Bukan solusi ideal karena membuat ulang sumber untuk tabel. Dan menggunakan ini dengan streamline / socket bukanlah cara yang efisien.
Maihan Nijat
0

Saya pikir MatTableDataSourceobjek tersebut terhubung dengan array data yang Anda berikan ke MatTableDataSourcekonstruktor.

Misalnya:

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

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

Jadi, ketika Anda harus mengubah data; perubahan pada daftar asli dataTabledan kemudian mencerminkan perubahan pada tabel dengan _updateChangeSubscription()metode panggilan aktif tableDS.

Misalnya:

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

Itu berhasil dengan saya melalui Angular 6.

nimeresam
sumber
4
Metode itu diawali dengan garis bawah _dan Anda menyebutnya?
Stephane
0

Ini berhasil untuk saya:

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

Jadi, Anda harus mendeklarasikan instance sumber data Anda sebagai MatTableDataSource

Raja Kecil
sumber
0

Saya melakukan beberapa penelitian lebih lanjut dan menemukan tempat ini untuk memberi saya apa yang saya butuhkan - terasa bersih dan terkait dengan pembaruan data saat di-refresh dari server: https://blog.angular-university.io/angular-material-data-table/

Sebagian besar kredit untuk halaman di atas. Di bawah ini adalah contoh bagaimana mat-selector dapat digunakan untuk memperbarui mat-table yang terikat ke sumber data pada saat perubahan pilihan. Saya menggunakan Angular 7. Maaf karena ekstensif, mencoba untuk menjadi lengkap tapi ringkas - Saya telah merobek sebanyak mungkin bagian yang tidak diperlukan. Dengan harapan ini dapat membantu orang lain maju lebih cepat!

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

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

organization.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);
  }
}
Henrik
sumber
0

Setelah membaca Tabel Material tidak memperbarui pembaruan data pos # 11638 Laporan Bug saya menemukan yang terbaik (baca, solusi termudah) adalah seperti yang disarankan oleh komentator terakhir 'shhdharmen' dengan saran untuk menggunakan EventEmitter.

Ini melibatkan beberapa perubahan sederhana pada kelas sumber data yang dihasilkan

yaitu) menambahkan variabel privat baru ke kelas sumber data Anda

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

dan di mana saya mendorong data baru ke array internal (this.data), saya memancarkan acara.

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

dan terakhir, ubah larik 'dataMutation' dalam metode 'hubungkan' - sebagai berikut

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

// ini adalah dataSource
this.guests = [];

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

// segarkan dataSource this.guests = Array.from (this.guest);

Igor Faoro
sumber
0
npm install @matheo/datasource

Saya merilis perpustakaan yang bertujuan untuk menjadi Sumber Data Material resmi di masa depan, mendukung semua jenis aliran input (urutkan, pagination, filter), dan beberapa konfigurasi dengan debugging untuk melihat cara kerjanya saat Anda sedang melakukan coding.

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

Anda dapat menemukan demo StackBlitz dan informasi lebih lanjut di sini:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

Saya akan senang mendengar pendapat Anda dan mendukung kasus penggunaan Anda jika perlu.
Selamat membuat kode!

Mateo Tibaquira
sumber
0

Saya telah mencoba ChangeDetectorRef, Subject dan BehaviourSubject tetapi apa yang berhasil untuk saya

dataSource = [];
this.dataSource = [];
 setTimeout(() =>{
     this.dataSource = this.tableData[data];
 },200)
Vishesh Mishra
sumber
apa yang terjadi di sini? Saya merasa seperti kesalahan penamaan variabel telah dibuat.
ChumiestBucket