2017-10-14 72 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); 
}); 
}