如何将 md-table 与 Angular 4 中的服务一起使用 [英] How to use md-table with services in Angular 4
问题描述
我在 Angular 世界中还是个新手,我正在尝试在 Angular Material 2 和 Angular 4 中使用新的 md-table 组件.
I am quite new in the angular world and i'm trying to use the new md-table component in Angular Material 2 with Angular 4.
我通过 API 创建了一项服务,该服务可检索简单的内容数组.现在我正在尝试使用此服务作为 md-table 的数据源,但我找不到从该服务中获取数据的方法(它总是返回一个空数组).
I've made a service from an API which retrieves simple arrays of content. Now I'm trying to use this service as a data source for the md-table but I can't find a way to get the data from the service (it always return me an empty array).
请注意,在使用 md-table 之前,我使用的是已经在使用的服务,并且运行正常.
Please note that before using md-table, I was using already using the service and it worked normally.
这是组件的代码:
import { Component, OnInit, ViewChild } from '@angular/core';
import {DataSource} from '@angular/cdk';
import {MdPaginator} from '@angular/material';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import { GroupService } from '../shared/group.service';
import { Group } from '../shared/group';
@Component({
selector: 'app-group-list',
templateUrl: './group-list.component.html',
styleUrls: ['./group-list.component.css'],
providers: [GroupService]
})
export class GroupListComponent implements OnInit{
public DisplayedColumns = ['name', 'email', 'directMembersCount'];
public groupDatabase = new GroupDatabase();
public dataSource : CustomDataSource | any;
@ViewChild(MdPaginator) paginator : MdPaginator;
constructor() {}
ngOnInit() {
this.dataSource = new CustomDataSource(this.groupDatabase, this.paginator);
console.log(this.dataSource);
}
}
export class GroupDatabase implements OnInit {
public dataChange: BehaviorSubject<Group[]> = new BehaviorSubject<Group[]>([]);
get data(): Group[] { return this.dataChange.value }
private _groupService : GroupService
private getAllGroups(){
return this._groupService
.getAllGroups();
}
constructor (){}
ngOnInit() {
this.getAllGroups();
console.log(this.getAllGroups());
}
}
export class CustomDataSource extends DataSource<any> {
constructor(private _groupDatabase = new GroupDatabase(), private _paginator: MdPaginator){
super();
}
connect(): Observable<Group[]> {
const displayDataChanges = [
this._groupDatabase.dataChange,
this._paginator.page
];
return Observable.merge(...displayDataChanges).map(() => {
const data = this._groupDatabase.data.slice();
console.log(data);
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
return data.splice(startIndex, this._paginator.pageSize);
})
}
disconnect() {}
}
这是 HTML 的代码:
Here is the code for the HTML :
<md-table #table [dataSource]="dataSource">
<ng-container *cdkColumnDef="name">
<md-header-cell *cdkCellDef>Nom</md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
</ng-container>
<ng-container *cdkColumnDef="email">
<md-header-cell *cdkCellDef>Email</md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.email}} </md-cell>
</ng-container>
<ng-container *cdkColumnDef="directMembersCount">
<md-header-cell *cdkCellDef>Nombre de membres</md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.directMembersCount}} </md-cell>
</ng-container>
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDef="let row; columns: DisplayedColumns;"></md-row>
</md-table>
<md-paginator #paginator
[length]="groupDatabase.data.length"
[pageIndex]="0"
[pageSize]="25"
[pageSizeOptions]="[5, 10, 25, 100]">
</md-paginator>
以及相关服务:
private groupApiUrl: string;
private groupsApiUrl: string;
private headers: Headers;
constructor(public http:Http, private config: Config) {
this.groupApiUrl = config.serverWithApi + "group";
this.groupsApiUrl = config.serverWithApi + "groups";
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
public getAllGroups = (): Observable<Group[]> => {
return this.http.get(this.groupsApiUrl)
.map((response: Response) => <Group[]>response.json())
.catch(this.handleError)
}
我不确定应该如何使用数据源调用服务,这就是为什么我像以前一样这样做;使用 ngOnInit 方法.
I'm not sure how I should call the service using the datasource, that's why I did it as I was doing before; using the ngOnInit method.
感谢您的帮助.
推荐答案
以下是通过 HTTP 检索数据的示例:https://plnkr.co/edit/mjQbufh7cUynD6qhF5Ap?p=preview
Here's an example of retrieving data through HTTP: https://plnkr.co/edit/mjQbufh7cUynD6qhF5Ap?p=preview
您遗漏了 GroupDatabase
没有在 dataChange
流上放置任何数据值的部分.它是一个以空数组开头的 BehaviorSubject
,但您不会在其上放置更多数据.这就是为什么该表只接收一个空数组.
You are missing a piece where GroupDatabase
does not put any data values on the dataChange
stream. It is a BehaviorSubject
that starts with an empty array but you do not put any more data on it. This is why the table is only receiving an empty array.
首先,要知道 ngOnInit
不会被 Angular 调用,因为 GroupDatabase
不是指令,也不是变更检测周期的一部分.
First, know that ngOnInit
will not be called by Angular since GroupDatabase
is not a directive and is not part of the change detection cycle.
相反,将 this.getAllGroups()
移动到 GroupDatabase
的构造函数.然后订阅它的结果:
Instead, move this.getAllGroups()
to the constructor of GroupDatabase
. and then subscribe to its result:
export class GroupDatabase {
public dataChange: BehaviorSubject<Group[]> = new BehaviorSubject<Group[]>([]);
get data(): Group[] { return this.dataChange.value }
constructor(groupService: GroupService) {
groupService.getAllGroups().subscribe(data => this.dataChange.next(data));
}
}
或者,完全摆脱 GroupDatabase,让您的 CustomDataSource
直接调用您的 GroupService.
Alternatively, get rid of GroupDatabase altogether and have your CustomDataSource
directly call your GroupService.
export class CustomDataSource extends DataSource<Group> {
constructor(
private _groupService: GroupService,
private _paginator: MdPaginator) { }
connect(): Observable<Group[]> {
const displayDataChanges = [
this._groupService.getAllGroups(),
this._paginator.page
];
return Observable.merge(...displayDataChanges).map((data, page) => {
const clonedData = data.slice();
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
return data.splice(startIndex, this._paginator.pageSize);
})
}
disconnect() {}
}
这篇关于如何将 md-table 与 Angular 4 中的服务一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!