Angular + Material - How to refresh a data source (mat-table)

前端 未结 23 1215
自闭症患者
自闭症患者 2020-11-28 01:59

I am using a mat-table to list the content of the users chosen languages. They can also add new languages using dialog panel. After they added a language and returned back.

相关标签:
23条回答
  • 2020-11-28 03:04

    Trigger a change detection by using ChangeDetectorRef in the refresh() method just after receiving the new data, inject ChangeDetectorRef in the constructor and use detectChanges like this:

    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();
        });
      }
    }
    
    0 讨论(0)
  • 2020-11-28 03:05
    this.dataSource = new MatTableDataSource<Element>(this.elements);
    

    Add this line below your action of add or delete the particular row.

    refresh() {
      this.authService.getAuthenticatedUser().subscribe((res) => {
        this.user = new MatTableDataSource<Element>(res);   
      });
    }
    
    0 讨论(0)
  • 2020-11-28 03:05

    In Angular 9, the secret is this.dataSource.data = this.dataSource.data;

    Example:

    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);
    }
    
    0 讨论(0)
  • 2020-11-28 03:05

    in my case (Angular 6+), I inherited from MatTableDataSource to create MyDataSource. Without calling after this.data = someArray

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

    data where not displayed

    class 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 
    
    0 讨论(0)
  • 2020-11-28 03:06

    I think the MatTableDataSource object is some way linked with the data array that you pass to MatTableDataSource constructor.

    For instance:

    dataTable: string[];
    tableDS: MatTableDataSource<string>;
    
    ngOnInit(){
       // here your pass dataTable to the dataSource
       this.tableDS = new MatTableDataSource(this.dataTable); 
    }
    

    So, when you have to change data; change on the original list dataTable and then reflect the change on the table by call _updateChangeSubscription() method on tableDS.

    For instance:

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

    That's work with me through Angular 6.

    0 讨论(0)
提交回复
热议问题