Angular + Material - Cách làm mới nguồn dữ liệu (mat-table)


120

Tôi đang sử dụng một bảng chiếu để liệt kê nội dung của các ngôn ngữ mà người dùng đã chọn. Họ cũng có thể thêm ngôn ngữ mới bằng bảng điều khiển hộp thoại. Sau khi họ thêm một ngôn ngữ và quay trở lại. Tôi muốn nguồn dữ liệu của mình làm mới để hiển thị những thay đổi mà họ đã thực hiện.

Tôi khởi tạo kho dữ liệu bằng cách lấy dữ liệu người dùng từ một dịch vụ và chuyển dữ liệu đó vào nguồn dữ liệu trong phương thức làm mới.

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
  }

}

Vì vậy, tôi đã cố gắng gọi một phương thức làm mới nơi tôi lấy lại người dùng từ chương trình phụ trợ và sau đó tôi khởi động lại nguồn dữ liệu. Tuy nhiên, điều này không hoạt động, không có thay đổi nào xảy ra.


1
Nếu bạn muốn kích hoạt sự thay đổi "từ nguồn dữ liệu", xin vui lòng có một cái nhìn tại stackoverflow.com/questions/47897694/...
Yennefer

Trình phát sự kiện có thể được sử dụng trong trường hợp này. stackoverflow.com/a/44858648/8300620
Rohit Parte

Câu trả lời:


58

Kích hoạt phát hiện thay đổi bằng cách sử dụng ChangeDetectorReftrong refresh()phương pháp ngay sau khi nhận được dữ liệu mới, đưa ChangeDetectorRef vào hàm tạo và sử dụng detector như sau:

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

9
Điều đó dường như hoạt động, đây có phải là cách thích hợp để làm điều đó? Có vẻ hơi hacky ...
Kay

Những cách khác là gì? Bạn có thể cung cấp các ví dụ trong giải pháp của mình để có câu trả lời đầy đủ không?
Kay


88

Tôi không biết liệu ChangeDetectorRefcó bắt buộc khi câu hỏi được tạo hay không, nhưng bây giờ thì đủ rồi:

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

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

Ví dụ:
StackBlitz


4
Mặc dù giải pháp này trên thực tế hoạt động, nhưng nó sẽ làm rối bộ phân trang vật liệu nếu phần tử được thêm vào đâu đó không phải trang đầu tiên của kết quả. Tôi hiểu rằng điều đó nằm ngoài phạm vi của câu hỏi này nhưng vì cả hai có liên quan đến nhau, bạn có tình cờ có giải pháp nhanh cho vấn đề đó mà bạn có thể thêm vào câu trả lời của mình không?
Hiệp sĩ

5
@Knight Tôi nghĩ bạn phải gán Paginator cho thuộc MatTableDataSource.paginatortính sau khi chế độ xem của Paginator đã được khởi tạo. Xem mô tả về paginatortài sản tại đây: material.angular.io/components/table/api#MatTableDataSource
Martin Schneider

Tham khảo tốt. Tôi đã không phát hiện ra điều đó trong tài liệu trước đây. Cảm ơn!
Hiệp sĩ

2
@ MA-Maddin bạn có thể nói rõ hơn về cách làm được không? thí dụ?
Nathanphan

@Nathanphan muộn, nhưng thêm một ví dụ;)
Martin Schneider

46

Vì vậy, đối với tôi, không ai đưa ra câu trả lời tốt cho vấn đề mà tôi gặp gần giống với @Kay. Đối với tôi đó là về việc sắp xếp, bảng sắp xếp không xảy ra những thay đổi trong tấm lót. Tôi nhắm đến câu trả lời này vì đó là chủ đề duy nhất tôi tìm thấy bằng cách tìm kiếm trên google. Tôi đang sử dụng Angular 6.

Như đã nói ở đây :

Vì bảng tối ưu hóa hiệu suất, nó sẽ không tự động kiểm tra các thay đổi đối với mảng dữ liệu. Thay vào đó, khi các đối tượng được thêm, xóa hoặc di chuyển trên mảng dữ liệu, bạn có thể kích hoạt cập nhật cho các hàng được hiển thị của bảng bằng cách gọi phương thức renderRows () của nó.

Vì vậy, bạn chỉ cần gọi renderRows () trong phương thức refresh () để thay đổi của bạn xuất hiện.

Xem tại đây để tích hợp.


1
Nếu nguồn dữ liệu bảng được thay đổi trên máy khách, câu trả lời này là những gì bạn có thể đang tìm kiếm. Hoạt động tuyệt vời!
Alvin Saldanha

Đây là câu trả lời đúng như vật liệu góc 8
Tom

Cảm ơn bạn. Nhưng từ đối tượng nào tôi nên gọi là "renderRows ()"? Nó có trong 'this.datasource' không?
WitnessTruth

19

Vì bạn đang sử dụng MatPaginator, bạn chỉ cần thực hiện bất kỳ thay đổi nào đối với paginator, điều này sẽ kích hoạt tải lại dữ liệu.

Thủ thuật đơn giản:

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

Điều này cập nhật kích thước trang thành kích thước trang hiện tại, vì vậy về cơ bản không có gì thay đổi, ngoại trừ _emitPageEvent()chức năng private cũng được gọi, kích hoạt tải lại bảng.


Tôi đã thử mã của bạn và nó không hoạt động (không có tác dụng). Tuy nhiên nextPage và sau đó beforePage lại hoạt động, nhưng không phải là giải pháp.
Ahmed Hasn.

_changePageSize()không công khai đúng không? Nó có an toàn để sử dụng không? Thêm thông tin về stackoverflow.com/questions/59093781/…
Jones

9
this.dataSource = new MatTableDataSource<Element>(this.elements);

Thêm dòng này bên dưới hành động thêm hoặc xóa hàng cụ thể của bạn.

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

cái gì thế này.elements
parvat

8

Cách tốt nhất để làm điều này là thêm một bổ sung có thể quan sát được vào việc triển khai Nguồn dữ liệu của bạn.

Trong phương thức kết nối, bạn nên sử dụng Observable.mergeđể đăng ký một mảng có thể quan sát bao gồm paginator.page, sort.sortChange, v.v. Bạn có thể thêm một chủ đề mới cho chủ đề này và gọi tiếp theo trên nó khi bạn cần làm mới.

một cái gì đó như thế này:

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

Và sau đó bạn có thể gọi recordChange$.next()để bắt đầu làm mới.

Đương nhiên, tôi sẽ gói cuộc gọi trong một phương thức refresh () và gọi nó ra khỏi cá thể nguồn dữ liệu w / trong thành phần và các kỹ thuật thích hợp khác.


Phương pháp này có thể đúng cách. Nó hoạt động tốt cho tôi
Manu

làm cách nào để thực hiện điều này khi tôi muốn mở rộng MatTableDataSource? Khi tôi thử ví dụ mã của bạn, tôi gặp lỗiProperty '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 kiểu MatTableDataSource triển khai phương thức kết nối với kiểu trả về khác. Nó sử dụng BehaviorSubject <t []> có nghĩa là bạn chỉ cần thay đổi ví dụ để trả về nó thay vì một Observable. Bạn vẫn có thể sử dụng DataSource nhưng nếu bạn phải sử dụng MatTableDataSource thì hãy trả về một BehaviorSubject được đăng ký để quan sát của bạn, giả sử bạn có một BehaviorSubject để bắt đầu. Hy vọng rằng sẽ giúp. Bạn có thể tham khảo nguồn cho MatTableDataSource để biết cú pháp chính xác của loại nguồn dữ liệu mới: github.com/angular/material2/blob/master/src/lib/table/…
jogi

7

Bạn chỉ có thể sử dụng chức năng kết nối nguồn dữ liệu

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

như vậy. 'data' là các giá trị mới cho dữ liệu


Có tiềm năng nhưng dường như không hoạt động. Nếu sau đó bạn truy cập this.datasource.data, nó không được cập nhật.
Rui Marques

4

Bạn có thể dễ dàng cập nhật dữ liệu của bảng bằng cách sử dụng "concat":

ví dụ:

language.component.ts

teachDS: any[] = [];

language.component.html

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

Và, khi bạn cập nhật dữ liệu (language.component.ts):

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

Khi bạn đang sử dụng góc "concat", hãy phát hiện những thay đổi của đối tượng (this.teachDS) và bạn không cần sử dụng thứ khác.

PD: Nó phù hợp với tôi ở góc 6 và 7, tôi không thử phiên bản khác.


2
Có, Nó hoạt động với tôi, là một vấn đề về tham chiếu và giá trị var, phát hiện thay đổi không thấy các thay đổi mới, vì vậy bạn cần cập nhật nó.
Mayra Rodriguez

Điều này có thể hoạt động nếu dataSource chỉ là một mảng nhưng không hiệu quả khi dataSource là một đối tượng MatTableDataSource.
Rui Marques


3

Chà, tôi đã gặp phải sự cố tương tự khi tôi thêm thứ gì đó vào nguồn dữ liệu và nó không tải lại.

Cách dễ nhất mà tôi thấy chỉ đơn giản là gán lại dữ liệu

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

Hoàn hảo!! Nó wokrs !! Cảm ơn :)
Nicolas

3

Trong Angular 9, bí mật là this.dataSource.data = this.dataSource.data;

Thí dụ:

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

2

Tôi đã đạt được một giải pháp tốt bằng cách sử dụng hai tài nguyên:

làm mới cả dataSource và paginator:

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

ví dụ dataSource được định nghĩa ở đây:

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

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

8
Vui lòng thêm giải thích cho câu trả lời của bạn, chỉ là mã đăng không hữu ích lắm và có thể khiến câu trả lời của bạn bị xóa.
TJ Wolschon

1

trong trường hợp của tôi (Angular 6+), tôi đã kế thừa từ MatTableDataSourceđể tạo MyDataSource. Không cần gọi sauthis.data = someArray

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

dữ liệu không được hiển thị

lớp 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 

1

Có hai cách để làm điều đó vì Angular Material không nhất quán và điều này rất ít được ghi chép lại. Bảng vật liệu dạng góc sẽ không cập nhật khi có hàng mới. Đáng ngạc nhiên là nó được cho biết là do các vấn đề về hiệu suất. Nhưng nó giống như một vấn đề thiết kế hơn, họ không thể thay đổi. Nó phải được mong đợi để bảng cập nhật khi hàng mới xảy ra. Nếu hành vi này không nên được kích hoạt theo mặc định, phải có một công tắc để tắt nó.

Dù sao, chúng tôi không thể thay đổi Vật liệu góc. Nhưng về cơ bản chúng ta có thể sử dụng một phương pháp được ghi chép rất ít để làm điều đó:

Một - nếu bạn sử dụng một mảng trực tiếp làm nguồn:

call table.renderRows()

nơi bảng là ViewChild của mat-table

Thứ hai - nếu bạn sử dụng tính năng sắp xếp và các tính năng khác

table.renderRows () đáng ngạc nhiên là sẽ không hoạt động. Bởi vì mat-table là không nhất quán ở đây. Bạn cần sử dụng một bản hack để cho biết nguồn đã thay đổi. Bạn làm điều đó với phương pháp này:

this.dataSource.data = yourDataSource;

nơi dataSource là trình bao bọc MatTableDataSource được sử dụng để sắp xếp và các tính năng khác.


0

Điều này đã làm việc cho tôi:

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

Không phải là một giải pháp lý tưởng vì nó tạo lại nguồn cho bảng và sử dụng điều này với ổ cắm / được sắp xếp hợp lý không phải là một cách hiệu quả.
Maihan Nijat

0

Tôi nghĩ rằng MatTableDataSourceđối tượng được liên kết với mảng dữ liệu mà bạn truyền cho hàm MatTableDataSourcetạo.

Ví dụ:

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

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

Vì vậy, khi bạn phải thay đổi dữ liệu; thay đổi trên danh sách ban đầu dataTablevà sau đó phản ánh sự thay đổi trên bảng theo _updateChangeSubscription()phương thức gọi trên tableDS.

Ví dụ:

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

Đó là công việc với tôi thông qua Angular 6.


4
Phương thức đó có tiền tố là dấu gạch dưới _và bạn gọi nó là gì?
Stephane

0

Điều này đang làm việc cho tôi:

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

Vì vậy, bạn nên khai báo phiên bản nguồn dữ liệu của mình là MatTableDataSource


0

Tôi đã thực hiện thêm một số nghiên cứu và nhận thấy nơi này cung cấp cho tôi những gì tôi cần - cảm thấy sạch sẽ và liên quan đến việc cập nhật dữ liệu khi được làm mới từ máy chủ: https://blog.angular-university.io/angular-material-data-table/

Hầu hết các khoản tín dụng cho trang trên. Dưới đây là ví dụ về cách có thể sử dụng công cụ chọn bảng để cập nhật bảng đệm liên kết với nguồn dữ liệu khi thay đổi lựa chọn. Tôi đang sử dụng Angular 7. Xin lỗi vì đã mở rộng, cố gắng hoàn thiện nhưng ngắn gọn - Tôi đã cắt ra nhiều phần không cần thiết nhất có thể. Với hy vọng này sẽ giúp người khác tiến nhanh hơn!

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

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

Tổ chức.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>

tổ chức.component.scss:

.spinner-container {
    height: 360px;
    width: 390px;
    position: fixed;
}

tổ chức.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);
  }
}

0

Sau khi đọc Bảng vật liệu không cập nhật bản cập nhật dữ liệu bài đăng # 11638 Báo cáo lỗi, tôi thấy cách tốt nhất (đọc, giải pháp dễ nhất) là theo đề xuất của người bình luận cuối cùng 'shhdharmen' với gợi ý sử dụng EventEmitter.

Điều này liên quan đến một vài thay đổi đơn giản đối với lớp nguồn dữ liệu đã tạo

tức là) thêm một biến riêng mới vào lớp nguồn dữ liệu của bạn

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

và khi tôi đẩy dữ liệu mới vào mảng nội bộ (this.data), tôi phát ra một sự kiện.

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

và cuối cùng, thay đổi mảng 'dataMutation' trong phương thức 'connect' - như sau

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

0

// đây là dataSource
this.guests = [];

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

// làm mới dữ liệuSource this.guests = Array.from (this.guest);


0
npm install @matheo/datasource

Tôi đã phát hành một thư viện nhằm trở thành Nguồn dữ liệu chính thức trong tương lai, hỗ trợ bất kỳ loại luồng đầu vào nào (sắp xếp, phân trang, bộ lọc) và một số cấu hình có gỡ lỗi để xem nó hoạt động như thế nào khi bạn viết mã.

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

Bạn có thể tìm thấy bản demo StackBlitz và thêm thông tin tại đây:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

Tôi rất vui khi nghe ý kiến ​​của bạn và hỗ trợ các trường hợp sử dụng của bạn nếu cần thiết.
Chúc bạn viết mã vui vẻ!


0

Tôi đã thử ChangeDetectorRef, Subject và BehaviourSubject nhưng điều gì phù hợp với tôi

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

những gì đang xảy ra ở đây? Tôi cảm thấy như những lỗi đặt tên biến đã được thực hiện.
ChumiestBucket
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.