사용자가 선택한 언어의 내용을 나열하기 위해 매트 테이블 을 사용하고 있습니다. 대화 패널을 사용하여 새 언어를 추가 할 수도 있습니다. 그들이 언어를 추가하고 돌아온 후. 데이터 소스를 새로 고쳐 변경 사항을 표시하고 싶습니다.
서비스에서 사용자 데이터를 가져 와서 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
에서 사용하여 변경 감지를 트리거 하고 생성자에 ChangeDetectorRef 를 refresh()
삽입 하고 다음 과 같이 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);
그렇게. 데이터 테이블의 새 값인 ‘데이터’