[angular] Angular + Material-데이터 소스를 새로 고치는 방법 (매트 테이블)

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

서비스에서 사용자 데이터를 가져 와서 refresh 메서드의 데이터 소스에 전달하여 데이터 저장소를 초기화합니다.

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
  }

}

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



답변

새 데이터를받은 직후 메서드 ChangeDetectorRef에서 사용하여 변경 감지를 트리거 하고 생성자에 ChangeDetectorRefrefresh()삽입 하고 다음 과 같이 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();
    });
  }
}


답변

는 나도 몰라 ChangeDetectorRef필요했다 질문을 만들 때,하지만 지금은이 충분하다 :

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

// ...

dataSource = new MatTableDataSource<MyDataType>();

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

예 :
StackBlitz


답변

그래서 나를 위해 아무도 내가 만난 문제에 대해 @Kay와 거의 같은 좋은 대답을주지 않았습니다. 나에게 그것은 정렬에 관한 것이고, 정렬 테이블은 매트에서 변경이 발생하지 않습니다. 이 답변은 Google 검색을 통해 찾은 유일한 주제이기 때문에 목적이 있습니다. Angular 6을 사용하고 있습니다.

여기에 말했듯 :

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

따라서 변경 사항이 표시되도록 refresh () 메서드 에서 renderRows () 를 호출하기 만하면 됩니다.

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


답변

을 사용하고 있기 때문에 페이지 MatPaginator지정자 만 변경하면 데이터가 다시로드됩니다.

간단한 트릭 :

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

이것은 페이지 크기를 현재 페이지 크기로 업데이트하므로 기본적으로 private _emitPageEvent()함수가 호출되어 테이블 다시로드를 트리거 하는 것을 제외하고는 아무것도 변경되지 않습니다 .


답변

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

특정 행을 추가하거나 삭제하는 작업 아래에이 행을 추가하십시오.

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


답변

이를 수행하는 가장 좋은 방법은 데이터 소스 구현에 Observable을 추가하는 것입니다.

connect 메소드 Observable.merge에서 paginator.page, sort.sortChange 등을 포함하는 Observable 배열을 구독하기 위해 이미 사용 하고 있어야 합니다. 여기에 새 주제를 추가하고 새로 고침해야 할 때 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 () 메서드로 래핑하고 구성 요소 및 기타 적절한 기술이있는 데이터 소스 인스턴스에서 호출합니다.


답변

데이터 소스 연결 기능을 사용할 수 있습니다.

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

그렇게. 데이터 테이블의 새 값인 ‘데이터’