2017-10-14 98 views
7

我正在使用mat表來列出用戶所選語言的內容。他們還可以使用對話框添加新的語言。他們添加了一種語言並返回後,我希望刷新數據源以顯示他們所做的更改。Angular +材質 - 如何刷新數據源(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); 
    }); 
    } 
} 

語言數據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 
    } 

} 

所以我試圖調用一個刷新方法,我從一開始用戶後端再重新初始化數據源。但是這不起作用,沒有發生變化。

回答

6

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

    } 

} 
+0

這似乎工作,這是做到這一點的正確方法?似乎有點哈克... – KHAN

+0

什麼是其他方式?您能否在您的解決方案中提供示例以獲得完整答案? – KHAN

+0

我現在只在我的項目中使用這一個。 – HDJEMAI

1

由於您使用MatPaginator,你只需要對paginator做任何更改,這會觸發數據重新加載。

簡單的一招:

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

此更新頁面大小,以當前頁面的大小,所以基本上沒有什麼變化,除了私人_emitPageEvent()函數被調用過,triggeing表重裝。

+0

可能工作,但似乎hacky ... – ConquerorsHaki

+0

我試過你的代碼,它不起作用(沒有效果)。然而,nextPage然後previousPage再次工作,但是沒有解決方案。 – ConquerorsHaki

3

最好的方法是在數據源實現中添加一個額外的可觀察元素。

在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()方法中,並將其從組件中的數據源實例和其他適當的技術中調用。

0

this.dataSource = new MatTableDataSource(this.elements);

在添加或刪除特定行的操作下面添加此行。

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