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 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.
您错过了一个GroupDatabase
没有在dataChange
流上放置任何数据值的部分。它BehaviorSubject
以一个空数组开头,但您不再在其上放置任何数据。这就是为什么该表只接收一个空数组。
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.
首先,要知道ngOnInit
Angular 不会调用它,因为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 CustomDataSource
directly 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() {}
}