【问题标题】:How to use md-table with services in Angular 4如何在 Angular 4 中将 md-table 与服务一起使用
【发布时间】:2017-07-10 14:08:38
【问题描述】:

我在 Angular 世界中很新,我正在尝试将 Angular Material 2 中的新 md-table 组件与 Angular 4 一起使用。

我通过一个 API 提供了一项服务,该服务检索简单的内容数组。 现在我正在尝试将此服务用作 md 表的数据源,但我找不到从服务中获取数据的方法(它总是返回一个空数组)。

请注意,在使用 md-table 之前,我已经在使用该服务并且它工作正常。

这是组件的代码:

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 的代码:

<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 方法。

感谢您的帮助。

【问题讨论】:

  • 看来我不是唯一一个想知道这个的人!一个关于这个的问题已经发布在 angular repo 上:#5670
  • 在 angular.io 网站上似乎没有任何专门针对 DataSource 的文档,仅在讨论其他主题时才会引用它,例如 cdk 表。我陷入困境的部分是在用户执行搜索后填充数据源。

标签: angular typescript angular-material2


【解决方案1】:

以下是通过 HTTP 检索数据的示例:https://plnkr.co/edit/mjQbufh7cUynD6qhF5Ap?p=preview


您错过了GroupDatabase 没有在dataChange 流上放置任何数据值的部分。这是一个BehaviorSubject,它以一个空数组开头,但您不再在上面放置任何数据。这就是表只接收空数组的原因。

首先,要知道 ngOnInit 不会被 Angular 调用,因为 GroupDatabase 不是指令,也不是变更检测周期的一部分。

相反,将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));
  }
}

或者,完全摆脱 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() {}
}

【讨论】:

  • 感谢您的回答。确实这解决了我的问题,但文档真的让我很困惑!
  • 对 GroupDatabase 使用第一种方法,您如何/何时传入服务?请在stackoverflow.com/questions/46456808/… 上查看我的问题,以了解有关该问题的更多详细信息并查看我尝试了什么。
  • @Andrew:我正在关注您在 Plunker 上的示例,该示例可以与 GitHub API 一起正常工作,但是当我更改 URL 并添加我的 http://localhost:4000/users 时,我收到以下错误:ERROR TypeError: t.json(...).map is not a function。我认为它正在影响这部分代码:return result.json().map(issue =&gt; {return {....}});。知道应该在那里修复什么吗?谢谢。
  • @k.vincent 这基本上意味着您的t 基本上没有正确格式化。您是否尝试过记录t?它是什么类型的?
猜你喜欢
  • 1970-01-01
  • 2016-07-21
  • 2018-05-06
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-07
  • 2018-06-25
相关资源
最近更新 更多