programing

각도 + 재료 - 데이터 원본을 새로 고치는 방법(매트 테이블)

easyjava 2023. 5. 4. 20:41
반응형

각도 + 재료 - 데이터 원본을 새로 고치는 방법(매트 테이블)

사용자가 선택한 언어의 내용을 나열하기 위해 매트 테이블을 사용하고 있습니다.또한 대화상자 패널을 사용하여 새로운 언어를 추가할 수 있습니다.그들이 언어를 추가하고 돌아온 후.데이터 소스를 새로 고쳐 변경 내용을 표시합니다.

서비스에서 사용자 데이터를 가져와 새로 고침 방법으로 데이터 소스에 전달하여 데이터스토어를 초기화합니다.

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

언어-데이터 소스.ts.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
  }

}

그래서 백엔드에서 사용자를 다시 가져온 다음 데이터 소스를 다시 초기화하는 새로 고침 방법을 호출하려고 했습니다.그러나 이 방법은 작동하지 않으며 변경 사항이 발생하지 않습니다.

저는 그것이ChangeDetectorRef질문이 생성될 때 필요했지만 이제 이 정도면 충분합니다.

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

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

예:
스택 블리츠

에서 를 사용하여 변경 감지를 트리거합니다.refresh()메소드는 새 데이터를 수신한 직후 생성자에 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();
    });
  }
}

그래서 저는 아무도 @Kay와 거의 비슷한 문제에 대해 좋은 답을 주지 않았습니다.저에게는 정렬에 관한 것입니다. 정렬 테이블은 매트에서 변경되지 않습니다.제가 구글 검색을 통해 찾을 수 있는 유일한 주제이기 때문에 이 답변을 드립니다.Angular 6를 사용하고 있습니다.

여기에 언급된 바와 같이:

테이블은 성능을 최적화하므로 데이터 배열의 변경 내용을 자동으로 확인하지 않습니다.대신 데이터 배열에서 개체를 추가, 제거 또는 이동할 때 renderRows() 메서드를 호출하여 테이블의 렌더링된 행에 대한 업데이트를 트리거할 수 있습니다.

따라서 refresh() 메서드에서 renderRows()를 호출하여 변경 내용을 표시하면 됩니다.

통합은 여기를 참조하십시오.

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

를 사용하고 있으므로 페이지 관리자를 변경하기만 하면 데이터를 다시 로드할 수 있습니다.

간단한 속임수:

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

크기로 개인 크기가 ._emitPageEvent()함수도 호출되어 테이블 다시 로드를 트리거합니다.

새 데이터 행을 추가한 후 인스턴스를 사용하지 않고 dataSource를 업데이트하여 재료 테이블을 새로 고쳤습니다.

HTML의 표:

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

addUser() in file component.ts:

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
}

데이터 소스 연결 기능을 사용하면 됩니다.

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

이와 같이데이터 테이블의 새 값인 'data'

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

특정 행 추가 또는 삭제 작업 아래에 이 행을 추가합니다.

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

데이터 소스에 무언가를 추가했는데 다시 로드되지 않는 비슷한 문제가 발생했습니다.

가장 쉬운 방법은 데이터를 재할당하는 것이었습니다.

let dataSource = ['a','b','c']
dataSource.push('d')
let cloned = dataSource.slice()
// Or in ECMAScript 2015 (ES6): // let cloned = [...dataSource]
dataSource = cloned

renderRows() 메서드를 사용할 수도 있습니다.

@ViewChild(MatTable, {static: false}) table : MatTable<any>  // Initialize

그리고나서

this.table.renderRows();

참고로, 다음 항목을 확인하십시오. Angular 10|9|8 Dialogs inline Row Operation을 사용하여 재료 테이블의 행 편집/추가/삭제

가장 좋은 방법은 데이터 소스 구현에 관찰 가능한 항목을 추가하는 것입니다.

연방법서이사합니다야해용미를 해야 합니다.Observable.mergepaginator.page, sort.sortChange를 합니다.새로 고침이 필요할 때 이 항목에 새 제목을 추가하고 다음을 호출할 수 있습니다.

다음과 같은 것:

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() 메서드로 통화를 마무리하고 구성 요소에 포함된 데이터 소스 인스턴스 및 기타 적절한 기술을 사용하여 호출합니다.

저는 이전의 제안들 중 몇 가지를 시도해 보았습니다.테이블을 업데이트하긴 하지만 몇 가지 우려 사항이 있습니다.

  1. 업데이트 중dataSource.data클론과 함께. 예를 들어.

    this.dataSource.data = [...this.dataSource.data];
    

    데이터가 크면 많은 메모리가 재할당됩니다.또한 MatTable은 테이블 내부의 모든 것이 새 것이므로 성능 문제를 일으킬 수 있다고 생각합니다.저는 제 테이블이 300줄 정도 되는 곳에서 테이블이 깜박이는 것을 발견했습니다.

  2. 하기 르기paginator._changePageSize를 들면 예를 ..

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

    그것은 방출할 것입니다.page 벤트이에 된 경우. 이미 처리한 적이 있습니다.page이벤트. 이벤트가 한 번 이상 실행될 수 있기 때문에 이상할 수 있습니다. 수 있습니다._changePageSize()간접적으로, 그것은 무한 루프를 일으킬 것입니다...

    저는 여기서 다른 해결책을 제안합니다.이 이블에않경는우에 의존하지 dataSourcefilter밭.밭.

  3. 할 수 .filter테이블 새로 고침을 트리거하는 필드:

    this.dataSource.filter = ' '; // Note that it is a space, not empty string
    

    이렇게 하면 테이블이 필터링을 수행하여 테이블의 UI를 업데이트합니다.하지만 그것은 당신만의 것을 필요로 합니다.dataSource.filterPredicate()필터링 논리를 처리할 수 있습니다.

두 가지 방법이 있습니다. 각도 재료는 일관성이 없고 문서화가 매우 미흡하기 때문입니다.새 행이 도착할 때 각 재료 테이블이 업데이트되지 않습니다.놀랍게도 성능 문제 때문이라고 합니다.하지만 이것은 설계상의 문제처럼 보이고, 그들은 그것을 바꿀 수 없습니다.새 행이 발생할 때 테이블이 업데이트되어야 합니다.기본적으로 이 동작을 사용하도록 설정하지 않으면 이 동작을 해제할 스위치가 있어야 합니다.

어쨌든 우리는 Angular Material을 변경할 수 없습니다.그러나 기본적으로 문서화되지 않은 방법을 사용하여 이를 수행할 수 있습니다.

하나 - 배열을 소스로 직접 사용하는 경우:

call table.renderRows()

여기서 table은 mat-table의 ViewChild입니다.

둘째 - 정렬 및 기타 기능을 사용하는 경우

table.renderRows()는 놀랍게도 작동하지 않습니다.매트 테이블은 여기서 일관성이 없기 때문입니다.소스가 변경되었음을 알려주기 위해 해킹을 사용해야 합니다.이 작업은 다음 방법으로 수행합니다.

this.dataSource.data = yourDataSource;

여기서 dataSource는 정렬 및 기타 기능에 사용되는 MatTableDataSource 래퍼입니다.

두 가지 리소스를 사용하여 좋은 솔루션을 달성했습니다.

dataSource 및 paginator를 모두 새로 고칩니다.

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

concat를 사용하여 표의 데이터를 쉽게 업데이트할 수 있습니다.

예:

language.component.ts

teachDS: any[] = [];

language.component.sys

<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" 각도를 사용할 때는 객체(이 DS.teach)의 변화를 감지하여 다른 것을 사용할 필요가 없습니다.

PD: 저는 6번과 7번 각도에서 작업할 수 있습니다. 다른 버전은 시도하지 않았습니다.

Angular 10에서는 다음과 같이 작동합니다.

HTML에서:

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

TypeScript 구성 요소에서 다음을 수행합니다.

myArray: MyObject[] = [];

addObjectToTable(object:MyObject): void {
    // To prevent duplicated objects

    if (object&& !this.myArray.includes(object)) {
        this.myArray.push(object);

        // To force the data table's datasource to refresh
        this.myArray= [...this.myArray];
    }
 }

ChangeDetectorRef, Subject and BehaviorSubject를 사용해 보았지만 다음과 같이 사용할 수 있습니다.

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

이것은 저에게 효과가 있었습니다.

refreshTableSorce() {
    this.dataSource = new MatTableDataSource<Element>(this.newSource);
}
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);   
    });
  }
}

나의 경우(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 

제 생각엔MatTableDataSource되어 있습니다.MatTableDataSource시공자

예를 들어:

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

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

해야 할 목록에서 합니다.dataTable그리고 나서 전화로 표에 변화를 반영합니다._updateChangeSubscription()에 있는 방법.tableDS.

예를 들어:

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

Angular 6를 통해 저와 함께 작업한 것입니다.

이것은 저에게 효과가 있습니다.

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

저는 좀 더 조사를 해보고 필요한 것을 제공하기 위해 이 장소를 찾았습니다. - 서버에서 새로 고쳤을 때 깨끗한 느낌과 업데이트 데이터와 관련이 있습니다. https://blog.angular-university.io/angular-material-data-table/

위 페이지에 대한 대부분의 크레딧입니다.다음은 선택 변경 시 데이터 소스에 바인딩된 매트 테이블을 업데이트하는 데 매트 선택기를 사용하는 방법의 예입니다.Angular 7을 사용하고 있습니다.광범위하게 말해서 죄송합니다. 완벽하지만 간결하게 하려고 노력합니다. 필요 없는 부분은 최대한 많이 찢어 놓았습니다.이것은 다른 누군가가 더 빨리 앞으로 나아갈 수 있도록 돕기를 바랍니다!

organization.model.ts:

export class Organization {
    id: number;
    name: String;
}

조직.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.vmdk:

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

자료표가 데이터 업데이트 업데이트하지 않음 #11638 버그 보고서를 읽은 후 제가 찾은 가장 좋은 방법(읽은 방법, 가장 쉬운 해결책)은 이벤트 이미터를 사용하자는 제안과 함께 최종 논평자 'shhdarmen'이 제안한 것입니다.

여기에는 생성된 데이터 소스 클래스에 대한 몇 가지 간단한 변경이 포함됩니다.

i) 데이터 원본 클래스에 새 개인 변수 추가

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

새 데이터를 내부 어레이(이 데이터)에 푸시하면 이벤트가 발생합니다.

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

마지막으로 'connect' 메서드에서 'dataMutation' 배열을 다음과 같이 변경합니다.

const dataMutations = [
    this.tableDataUpdated,
    this.paginator.page,
    this.sort.sortChange
];
// this is the dataSource    
this.guests = [];

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

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

다음과 같이 표시됩니다.refresh()함수는 새 인스턴스를 적절하게 추가하는 중입니다.teachDS데이터 소스그러나 테이블은 업데이트하라는 지시를 받지 않아 업데이트되지 않습니다.

Angular에 데이터 소스의 변경 사항을 모니터링하고 필요에 따라 다음을 사용하여 테이블을 업데이트하도록 지시할 수 있습니다.ChangeDetectorRef서비스.

ChangeDetectorRef서비스를 먼저 구성 요소에 주입해야 합니다.

import { ChangeDetectorRef } from '@angular/core';

constructor(
            private authService: AuthService, 
            private dialog: MatDialog, 
            private changeDetectorRef: ChangeDetectorRef
) { }

그런 다음 데이터 원본을 새로 고친 후refresh() "Angular"를 을 확인하고 을 업데이트하도록 할 수 있습니다.detectChanges()에 있는 changeDetectorRef:

refresh() {
  this.authService.getAuthenticatedUser().subscribe((res) => {
    this.user = res;
    this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);
    this.changeDetectorRef.detectChanges();  // <-- Tell Angular to check for changes
  });
}

결과적으로 테이블은 데이터 원본 변경 사항을 반영하도록 업데이트되어야 합니다.

Angular 15에서는 이전 솔루션 중 어떤 것도 저에게 효과가 없었습니다.

대신에, 나는 사용해야 했습니다.

 @ViewChild(MatTable) table!: MatTable<MyStruct>;
 ...
 this.table.renderRows();

예제는 StackBlitz 예제를 참조하십시오.

데이터에 대해 단순 배열을 사용하는 대신 datasource.ts 파일을 설정할 때 다음과 같은 데이터에 대해 제목과 getter/setter를 사용합니다.

 dataStream = new BehaviorSubject<DataSourceItem[]>(EXAMPLE_DATA);
 set data(v: DataSourceItem[]) { this.dataStream.next(v); }
 get data(): DataSourceItem[] { return this.dataStream.value; }

당신의 럼그당의에서.connect()은 sofunction과 합니다.

return merge(this.dataStream, this.paginator.page, this.sort.sortChange)

이제 dataSource.data 배열을 변경할 때...이와 같이:

this.dataSource.data = ['my','new','item']

그것은 그것을 촉발할 것입니다.this.dataStream.next(v)와 처부터끝지에서.connect()함수는 테이블을 올바르게 업데이트합니다.

전체 작동 예는 https://stackblitz.com/edit/angular-material2-issue-yzhsml?file=app%2Fdata-table-datasource.ts 에서 확인할 수 있습니다.

이거 먹어봐요.도움이 될 수도 있습니다.

사용자를 로드하는 기능으로 시작합니다.

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

}

는 사용자를 삭제한 후 테이블을 새로 고치는 데 사용되는 새로 고침 기능을 정의합니다.

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

이제 아래와 같이 사용자 프로세스를 삭제한 후 refresh() 기능을 호출할 수 있습니다.

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

언급URL : https://stackoverflow.com/questions/46746598/angular-material-how-to-refresh-a-data-source-mat-table

반응형