如何将 md-table 与 Angular 4 中的服务一起使用 [英] How to use md-table with services in Angular 4

查看:24
本文介绍了如何将 md-table 与 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆