typescript 如何将 md-table 与 Angular 4 中的服务一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45014257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use md-table with services in Angular 4
提问by Helongh
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.
我在角度世界中很新,我正在尝试在 Angular Material 2 和 Angular 4 中使用新的 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).
我从一个 API 中创建了一个服务,它检索简单的内容数组。现在我正在尝试使用此服务作为 md-table 的数据源,但我找不到从服务中获取数据的方法(它总是返回一个空数组)。
Please note that before using md-table, I was using already using the service and it worked normally.
请注意,在使用 md-table 之前,我已经在使用该服务并且它工作正常。
Here is the code for the component :
这是组件的代码:
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() {}
}
Here is the code for the HTML :
这是 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>
And the concerned service :
以及相关服务:
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)
}
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.
我不确定应该如何使用数据源调用服务,这就是为什么我像以前一样这样做;使用 ngOnInit 方法。
Thanks for you help.
谢谢你的帮助。
回答by Andrew Seguin
Here's an example of retrieving data through HTTP: https://plnkr.co/edit/mjQbufh7cUynD6qhF5Ap?p=preview
以下是通过 HTTP 检索数据的示例:https: //plnkr.co/edit/mjQbufh7cUynD6qhF5Ap?p=preview
You are missing a piece where GroupDatabasedoes not put any data values on the dataChangestream. It is a BehaviorSubjectthat 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.
您错过了一个GroupDatabase没有在dataChange流上放置任何数据值的部分。它BehaviorSubject以一个空数组开头,但您不再在其上放置任何数据。这就是为什么该表只接收一个空数组。
First, know that ngOnInitwill not be called by Angular since GroupDatabaseis not a directive and is not part of the change detection cycle.
首先,要知道ngOnInitAngular 不会调用它,因为GroupDatabase它不是指令,也不是更改检测周期的一部分。
Instead, move this.getAllGroups()to the constructor of GroupDatabase. and then subscribe to its result:
相反,移动this.getAllGroups()到 的构造函数GroupDatabase。然后订阅它的结果:
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));
}
}
Alternatively, get rid of GroupDatabase altogether and have your CustomDataSourcedirectly call your GroupService.
或者,完全摆脱 GroupDatabase 并让您CustomDataSource直接调用您的 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() {}
}

