【问题标题】:Angular + Material - How to refresh a data source (mat-table)Angular + Material - 如何刷新数据源(mat-table)
【发布时间】:2018-03-26 13:47:38
【问题描述】:

我正在使用mat-table 列出用户选择的语言的内容。他们还可以使用对话面板添加新语言。在他们添加了一种语言并返回后。我希望我的数据源刷新以显示他们所做的更改。

我通过从服务获取用户数据并在刷新方法中将其传递到数据源来初始化数据存储。

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

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

}

所以我尝试调用刷新方法,再次从后端获取用户,然后重新初始化数据源。但是这不起作用,没有发生任何变化。

【问题讨论】:

标签: angular angular-material refresh


【解决方案1】:

我不知道创建问题时是否需要ChangeDetectorRef,但现在这就足够了:

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

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

示例:
StackBlitz

【讨论】:

  • 虽然此解决方案确实有效,但如果将元素添加到结果第一页以外的位置,它确实会弄乱材料分页器。我知道这超出了这个问题的范围,但由于这两者是相关的,你是否碰巧有一个快速的解决方案可以添加到你的答案中?
  • @Knight 我认为您必须在 Paginator 的视图初始化后将 Paginator 分配给 MatTableDataSource.paginator 属性。在此处查看paginator 属性的描述:material.angular.io/components/table/api#MatTableDataSource
  • 很好的参考。我之前在文档中没有发现这一点。谢谢!
  • @MA-Maddin 你能更具体地说明如何做吗?例子?
【解决方案2】:

refresh() 方法中使用ChangeDetectorRef 触发更改检测 收到新数据后,在构造函数中注入ChangeDetectorRef,并像这样使用detectChanges

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

【讨论】:

  • 这似乎可行,这是正确的做法吗?似乎有点 hacky...
  • 其他方法是什么?您能否在解决方案中提供示例以获得完整答案?
  • 这让我的 who matTable 变得反应迟钝。一定是做错了什么。
【解决方案3】:

所以对我来说,没有人对我遇到的问题给出很好的答案,这与@Kay 几乎相同。对我来说这是关于排序的,排序表中的垫子不会发生变化。 我打算这个答案,因为它是我通过搜索谷歌找到的唯一主题。 我正在使用 Angular 6。

here所说:

由于该表针对性能进行了优化,它不会自动检查对数据数组的更改。相反,当在数据数组上添加、删除或移动对象时,您可以通过调用其 renderRows() 方法来触发对表的渲染行的更新。

因此,您只需在 refresh() 方法中调用 renderRows() 即可显示您的更改。

请参阅here 了解集成。

【讨论】:

  • 如果客户端的表数据源发生了变化,这个答案可能就是你要找的。效果很好!
  • 这是角材料 8 的正确答案
  • 谢谢。但是我应该从哪个对象调用“renderRows()”?它在“this.datasource”中吗?
【解决方案4】:

由于您使用的是MatPaginator,您只需对分页器进行任何更改,这将触发数据重新加载。

简单的技巧:

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

这会将页面大小更新为当前页面大小,因此基本上没有任何变化,除了私有 _emitPageEvent() 函数也被调用,触发表重新加载。

【讨论】:

  • 我试过你的代码,但它不起作用(没有效果)。但是 nextPage 和 previousPage 再次起作用,但不是解决方案。
  • _changePageSize() 不是公开的吗?使用安全吗?更多关于stackoverflow.com/questions/59093781/…
【解决方案5】:

在 Angular 9 中,秘密是 this.dataSource.data = this.dataSource.data;

例子:

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

【讨论】:

  • 这真是太奇怪了,Angular 材料太丢脸了!
  • @Arash 我同意你的观点:/ 但我更喜欢这个解决方案而不是数百行的正确解决方案......
【解决方案6】:

你可以只使用数据源连接功能

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

像这样。 'data' 是数据表的新值

【讨论】:

  • 有潜力,但似乎不起作用。如果之后你访问 this.datasource.data,它没有更新。
【解决方案7】:
this.dataSource = new MatTableDataSource<Element>(this.elements);

在添加或删除特定行的操作下方添加此行。

refresh() {
  this.authService.getAuthenticatedUser().subscribe((res) => {
    this.user = new MatTableDataSource<Element>(res);   
  });
}

【讨论】:

  • this.elements 是什么
  • 这会破坏排序吗?
【解决方案8】:

最好的方法是在你的数据源实现中添加一个额外的 observable。

在 connect 方法中,您应该已经使用 Observable.merge 订阅了一个包含 paginator.page、sort.sortChange 等的 observables 数组。您可以为此添加一个新主题并在您使用时调用 next需要引起刷新。

类似这样的:

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

然后您可以调用recordChange$.next() 来启动刷新。

当然,我会将调用包装在 refresh() 方法中,并从组件中的数据源实例和其他适当的技术中调用它。

【讨论】:

  • 这种方法可能是正确的方法。对我来说很好用
  • 当我想扩展 MatTableDataSource 时如何实现?当我尝试您的代码示例时,我收到错误 Property 'connect' in type 'customDataSource&lt;T&gt;' is not assignable to the same property in base type 'MatTableDataSource&lt;T&gt;'. Type '() =&gt; Observable&lt;any&gt;' is not assignable to type '() =&gt; BehaviorSubject&lt;T[]&gt;'. Type 'Observable&lt;any&gt;' is not assignable to type 'BehaviorSubject&lt;T[]&gt;'. Property '_value' is missing in type 'Observable&lt;any&gt;'.
  • @Maurice 类型 MatTableDataSource 实现了具有不同返回类型的连接方法。它使用 BehaviorSubject 这意味着您只需要更改示例即可返回 this 而不是 Observable。您应该仍然可以使用 DataSource 但如果您必须使用 MatTableDataSource 然后返回一个订阅您的 observable 的 BehaviorSubject ,假设您有一个开始。希望有帮助。您可以参考 MatTableDataSource 的源代码,了解新数据源类型的确切语法:github.com/angular/material2/blob/master/src/lib/table/…
【解决方案9】:

你也可以使用 renderRows() 方法。

@ViewChild(MatTable, {static: false}) table : MatTable // 初始化

那么 this.table.renderRows();

作为参考,请查看 -: https://www.freakyjolly.com/angular-7-8-edit-add-delete-rows-in-material-table-with-using-dialogs-inline-row-operation/

【讨论】:

    【解决方案10】:

    好吧,我遇到了一个类似的问题,我在数据源中添加了一些东西,但它没有重新加载。

    我发现最简单的方法就是重新分配数据

    let dataSource = ['a','b','c']
    dataSource.push('d')
    let cloned = dataSource.slice()
    // OR IN ES6 // let cloned = [...dataSource]
    dataSource = cloned
    

    【讨论】:

    • 完美!!它工作!谢谢:)
    【解决方案11】:

    添加新数据行后,我通过更新 dataSource 而不使用其实例来刷新我的材料表。

    HTML 表格:

    <table mat-table #table [dataSource]="myDataArray">
    

    component.ts 中的addUser():

    public USER_DATA: user[] = [];
    
    
    public newUser = {userName: "ABC", email: "abc@gmail.com"};
    public myDataArray: any;
    
    
    addUser() {
        const newUsersArray = this.USER_DATA;
        newUsersArray.push(this.newUser);
        this.myDataArray = [...newUsersArray];//refresh the dataSource
        
      }
    

    【讨论】:

      【解决方案12】:

      我使用两种资源实现了一个很好的解决方案:

      同时刷新数据源和分页器:

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

      例如 dataSource 在这里定义:

          users: User[];
          ...
          dataSource = new MatTableDataSource(this.users);
          ...
          this.dataSource.paginator = this.paginator;
          ...
      

      【讨论】:

        【解决方案13】:

        有两种方法可以做到这一点,因为 Angular Material 不一致,而且文档记录非常差。当新行到达时,角度材料表不会更新。令人惊讶的是,它被告知这是因为性能问题。但它看起来更像是一个设计问题,它们无法更改。当出现新行时,应该预期表会更新。如果默认情况下不应启用此行为,则应该有一个开关将其关闭。

        无论如何,我们无法更改 Angular Material。但是我们基本上可以使用文档记录非常差的方法来做到这一点:

        一个 - 如果您直接使用数组作为源:

        call table.renderRows()
        

        table 是 mat-table 的 ViewChild

        其次 - 如果您使用排序和其他功能

        table.renderRows() 出人意料地不起作用。因为这里的 mat-table 不一致。您需要使用 hack 来告诉源已更改。你用这个方法来做:

        this.dataSource.data = yourDataSource;
        

        其中 dataSource 是 MatTableDataSource 包装器,用于排序和其他功能。

        【讨论】:

          【解决方案14】:

          您可以使用“concat”轻松更新表的数据:

          例如:

          language.component.ts

          teachDS: any[] = [];
          

          language.component.html

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

          并且,当您更新数据时(language.component.ts):

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

          当您使用“concat”角度检测对象(this.teachDS)的变化时,您不需要使用其他东西。

          PD:在 Angular 6 和 7 中对我有用,我没有尝试其他版本。

          【讨论】:

          • 是的,它对我有用,是关于引用和值 var 的问题,更改检测没有看到新的更改,因为你需要更新它。
          • 如果 dataSource 只是一个数组,但当 dataSource 是 MatTableDataSource 对象时,这可能有效。
          【解决方案15】:

          这对我有用:

          refreshTableSorce() {
              this.dataSource = new MatTableDataSource<Element>(this.newSource);
          }
          

          【讨论】:

          • 不是一个理想的解决方案,因为它会为表重新创建源。并且将其与流线型/套接字一起使用效率不高。
          【解决方案16】:

          我尝试过 ChangeDetectorRef、Subject 和 BehaviourSubject,但什么对我有用

          dataSource = [];
          this.dataSource = [];
           setTimeout(() =>{
               this.dataSource = this.tableData[data];
           },200)
          

          【讨论】:

          • 这是怎么回事?我觉得变量命名错误。
          【解决方案17】:
          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);   
              });
            }
          }
          

          【讨论】:

          • 请为您的答案添加解释,仅发布代码并没有太大帮助,可能会导致您的答案被删除。
          【解决方案18】:

          在我的情况下(Angular 6+),我从MatTableDataSource 继承来创建MyDataSource无需调用this.data = someArray

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

          未显示的数据

          类 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 
          

          【讨论】:

            【解决方案19】:

            在 Angular 10 中,这对我有用: 在 HTML 中:

            <mat-table [dataSource]="myArray">
            

            在组件TS中:

                myArray: MyObject[] = [];
            
             addObjectToTable(object:MyObject): void {
                  //TO PREVENT DUPLICATED OBJECTS
                if (object&& !this.myArray.includes(object)) {
                  this.myArray.push(object);
                  // TO FORCE DATA-TABLE's DATASOURCE TO REFRESH
                  this.myArray= [...this.myArray];
                }
              }
            

            【讨论】:

            • 我不确定这是否是最好的解决方案,但这对我有用。如果有其他更好的解决方案,请提出建议。
            【解决方案20】:

            我已经尝试了之前的一些建议。它确实更新了表格,但我有一些担忧:

            1. 使用其克隆更新dataSource.data。例如
            this.dataSource.data = [...this.dataSource.data];
            

            如果数据很大,这将重新分配大量内存。此外,MatTable 认为表中的所有内容都是新的,因此可能会导致性能问题。我发现我的表在我的表大约有 300 行的地方闪烁。

            1. 致电paginator._changePageSize。例如
            this.paginator._changePageSize(this.paginator.pageSize);
            

            它将发出page 事件。如果您已经对page 事件进行了一些处理。您可能会觉得这很奇怪,因为该事件可能会被多次触发。并且如果事件以某种方式间接触发_changePageSize(),则可能会导致无限循环......

            我在这里建议另一种解决方案。如果您的表不依赖于dataSourcefilter 字段。

            1. 您可以更新filter 字段以触发表刷新:
            this.dataSource.filter = ' '; // Note that it is a space, not empty string
            

            通过这样做,表格将执行过滤,从而更新表格的 UI。但它需要你自己的dataSource.filterPredicate() 来处理你的过滤逻辑。

            【讨论】:

              【解决方案21】:

              我认为MatTableDataSource 对象以某种方式与您传递给MatTableDataSource 构造函数的数据数组相关联。

              例如:

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

              所以,当您必须更改数据时;更改原始列表dataTable,然后通过在tableDS 上调用_updateChangeSubscription() 方法将更改反映在表上。

              例如:

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

              这对我来说是通过 Angular 6 工作的。

              【讨论】:

              • 那个方法的前缀是一个下划线_你叫它?
              【解决方案22】:

              这对我有用:

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

              所以你应该将你的数据源实例声明为MatTableDataSource

              【讨论】:

                【解决方案23】:

                我做了更多的研究,发现这个地方给了我我需要的东西——感觉很干净,并且在从服务器刷新时与更新数据有关: https://blog.angular-university.io/angular-material-data-table/

                以上页面的大部分功劳。下面是一个示例,说明如何使用 mat-selector 在更改选择时更新绑定到数据源的 mat-table。我正在使用 Angular 7。对不起,我试图做到完整但简洁——我已经尽可能多地删除了不需要的部分。希望以此帮助其他人更快地前进!

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

                组织数据源.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();
                  }
                }
                

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

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

                【讨论】:

                  【解决方案24】:

                  看完Material Table not updating post data update #11638 Bug Report 我发现最好的(阅读,最简单的解决方案)是最终评论者“shhdharmen”的建议,并建议使用 EventEmitter。

                  这涉及对生成的数据源类的一些简单更改

                  ie) 为你的数据源类添加一个新的私有变量

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

                  当我将新数据推送到内部数组 (this.data) 时,我会发出一个事件。

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

                  最后,在 'connect' 方法中更改 'dataMutation' 数组 - 如下

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

                  【讨论】:

                    【解决方案25】:

                    // 这是数据源
                    this.guests = [];

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

                    //刷新数据源 this.guests = Array.from(this.guest);

                    【讨论】:

                      【解决方案26】:

                      试试这个可能对你有帮助

                      从加载用户的函数开始。

                      loadUser() {
                          this.userService.getListOfUsers().subscribe()
                              (response: any) => {
                                  this.dataSource = response
                                  this.dataSource.paginator = this.paginator;
                              }
                      
                      }
                      

                      define刷新函数,用于删除用户后刷新表。

                      refresh() {
                          this.loadUser();
                          this.dataSource.data = [...this.dataSource.data];
                          this.dataSource.paginator = this.paginator;
                      }
                      

                      现在您可以在删除用户进程后调用 refresh() 函数,如下所示。

                      deleteUser() {
                          ...... 
                          this.refresh()
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2021-07-08
                        • 2019-07-28
                        • 2018-06-02
                        • 2020-02-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多