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

前端 未结 23 1212
自闭症患者
自闭症患者 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 02:39

    Since you are using MatPaginator, you just need to do any change to paginator, this triggers data reload.

    Simple trick:

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

    This updates the page size to the current page size, so basically nothing changes, except the private _emitPageEvent() function is called too, triggeing table reload.

    0 讨论(0)
  • 2020-11-28 02:39

    Best way to do this is by adding an additional observable to your Datasource implementation.

    In the connect method you should already be using Observable.merge to subscribe to an array of observables that include the paginator.page, sort.sortChange, etc. You can add a new subject to this and call next on it when you need to cause a refresh.

    something like this:

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

    And then you can call recordChange$.next() to initiate a refresh.

    Naturally I would wrap the call in a refresh() method and call it off of the datasource instance w/in the component, and other proper techniques.

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

    After reading Material Table not updating post data update #11638 Bug Report I found the best (read, the easiest solution) was as suggested by the final commentor 'shhdharmen' with a suggestion to use an EventEmitter.

    This involves a few simple changes to the generated datasource class

    ie) add a new private variable to your datasource class

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

    and where I push new data to the internal array (this.data), I emit an event.

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

    and finally, change the 'dataMutation' array in the 'connect' method - as follows

    const dataMutations = [
        this.tableDataUpdated,
        this.paginator.page,
        this.sort.sortChange
    ];
    
    0 讨论(0)
  • 2020-11-28 02:45

    This is working for me:

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

    So you should declare your datasource instance as MatTableDataSource

    0 讨论(0)
  • 2020-11-28 02:46

    // this is the dataSource
    this.guests = [];

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

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

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