Angular 5 Material Table无法从服务获取数据 [英] Angular 5 Material Table not getting data from service

查看:54
本文介绍了Angular 5 Material Table无法从服务获取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Angular(5)和Material表简单地显示来自MySQL数据库的数据.我拥有的代码已成功编译,并且出现了带有列名和分页按钮的表,但是该表中没有数据.我知道API调用正确返回了数据,并且我知道服务正在调用API(我可以在浏览器的网络检查器中看到正确的数据).在

I am trying to simply display data from a MySQL database using Angular (5) with a Material table. The code I have compiles successfully, and a table with the column names and pagination buttons appears, but there is no data shown in the table. I know that the API call is returning data correctly, and I know that the service is calling the API (I can see the correct data in the network inspector in the browser). There is an error shown in the browser of

TypeError: _co.unitTypeDatabase.data is undefined
Stack trace:
View_UnitTypeComponent_0/<@ng:///AppModule/UnitTypeComponent.ngfactory.js:136:9 ...

似乎错误是指html代码中引用unitTypeDatabase.data.length的部分.如果未定义,那么它将解释为什么表中也没有数据.我不知道的是为什么.我认为这与创建new UnitTypeDatabase的方式/时间/位置有关,但是鉴于该服务已成功调用,因此我不确定从何处去.这是我的代码:

It would appear that the error is referring to the part in the html code referring to unitTypeDatabase.data.length. If that is undefined, then it would explain why there is no data in the table as well. What I can't figure out is why that is undefined. I think it has to do with how/when/where I am creating the new UnitTypeDatabase, but given that the service is successfully being called I'm not sure where to go from here. Here is the code I have:

unit-type.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { UnitType } from './unit-type';
import { UnitTypeService } from './unit-type.service';
import {DataSource} from '@angular/cdk/collections';
import {MdPaginator} from '@angular/material';
import {Observable} from 'rxjs/Observable';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';

@Component({
  selector: 'app-unit-type',
  templateUrl: './unit-type.component.html',
  styleUrls: ['./unit-type.component.scss'],
  providers: [UnitTypeService]
})
export class UnitTypeComponent implements OnInit {
  public displayedColumns = ['unitTypeID', 'unitTypeName'];
  public unitTypeDatabase: UnitTypeDatabase | null;
  public dataSource: UnitTypeDataSource | null;

  @ViewChild(MdPaginator) paginator: MdPaginator;

  constructor(private unitTypeService: UnitTypeService) {}

  ngOnInit() {
      this.unitTypeDatabase = new UnitTypeDatabase(this.unitTypeService);
      this.dataSource = new UnitTypeDataSource(this.unitTypeDatabase, this.paginator);
  }
}

export class UnitTypeDataSource extends DataSource<UnitType> {
  constructor(private _unitTypeDatabase: UnitTypeDatabase, private _paginator: MdPaginator) {
      super();
    }

  connect(): Observable<UnitType[]> {
    const displayDataChanges = [
      this._unitTypeDatabase.dataChange,
      this._paginator.page
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      const data = this._unitTypeDatabase.data.slice();

      const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
      return data.splice(startIndex, this._paginator.pageSize);
    })
  }

  disconnect() {}
}

export class UnitTypeDatabase {
  /** Stream that emits whenever the data has been modified. */
  public dataChange: BehaviorSubject<UnitType[]> = new BehaviorSubject<UnitType[]>([]);
  get data(): UnitType[] { return this.dataChange.value; }

  constructor(unitTypeService: UnitTypeService) {
      unitTypeService.getAllUnitTypes().subscribe(data => this.dataChange.next(data));
  }
}

unit-type.component.html

<div class="example-container mat-elevation-z8">
  <md-table #table [dataSource]="dataSource">

    <!-- ID Column -->
    <ng-container mdColumnDef="unitTypeID">
      <md-header-cell *mdHeaderCellDef> ID </md-header-cell>
      <md-cell *mdCellDef="let row"> {{row.unitTypeID}} </md-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container mdColumnDef="unitTypeName">
      <md-header-cell *mdHeaderCellDef> Name </md-header-cell>
      <md-cell *mdCellDef="let row"> {{row.unitTypeName}} </md-cell>
    </ng-container>

    <md-header-row *mdHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *mdRowDef="let row; columns: displayedColumns;"></md-row>
  </md-table>

  <md-paginator #paginator
            [length]="unitTypeDatabase.data.length"
            [pageIndex]="0"
            [pageSize]="25"
            [pageSizeOptions]="[5, 10, 25, 100]">
  </md-paginator>
</div>

unit-type.ts

export class UnitType {
    constructor(
        public unitTypeID: number,
        public unitTypeName: string
    ){}
}

unit-type.service.ts

import { Injectable } from '@angular/core';
import { UnitType } from './unit-type';
import { Headers, Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class UnitTypeService {
  private unit_types_Url = 'api/unit-types';  // URL to web api
  private headers = new Headers({'Content-Type': 'application/json'});

  constructor(private http: Http) { }

  getAllUnitTypes(): Observable<UnitType[]> {
    return this.http.get(this.unit_types_Url)
           .map(response => response.json().data as UnitType[]);
  }
}

我从Material网站上的示例开始,但是并没有使用服务来检索数据.我还尝试从如何匹配问题和答案在Angular 4中将md-table与服务一起使用,但是我一定会丢失一些东西.希望有人可以快速发现这是一个显而易见的简单错误或误解.谢谢!

I started with the example from the Material site, but that does not retrieve data using a service. I also tried to match the question and answer from How to use md-table with services in Angular 4 but I must be missing something. Hopefully it is an obvious and simple error or misunderstanding that someone can quickly spot. Thanks!

修改 完整的堆栈跟踪为:

Edit The full stack trace is:

ERROR TypeError: _this._unitTypeDatabase.data is undefined
Stack trace:
[208]/UnitTypeDataSource.prototype.connect/<@http://localhost:4200/main.bundle.js:93:17
MapSubscriber.prototype._next@http://localhost:4200/vendor.bundle.js:51417:22
Subscriber.prototype.next@http://localhost:4200/vendor.bundle.js:37214:13
OuterSubscriber.prototype.notifyNext@http://localhost:4200/vendor.bundle.js:48573:9
InnerSubscriber.prototype._next@http://localhost:4200/vendor.bundle.js:117362:9
Subscriber.prototype.next@http://localhost:4200/vendor.bundle.js:37214:13
Subject.prototype.next@http://localhost:4200/vendor.bundle.js:26457:17
BehaviorSubject.prototype.next@http://localhost:4200/vendor.bundle.js:49978:9
UnitTypeDatabase/<@http://localhost:4200/main.bundle.js:122:78
SafeSubscriber.prototype.__tryOrUnsub@http://localhost:4200/vendor.bundle.js:37363:13
SafeSubscriber.prototype.next@http://localhost:4200/vendor.bundle.js:37310:17
Subscriber.prototype._next@http://localhost:4200/vendor.bundle.js:37250:9
Subscriber.prototype.next@http://localhost:4200/vendor.bundle.js:37214:13
MapSubscriber.prototype._next@http://localhost:4200/vendor.bundle.js:51423:9
Subscriber.prototype.next@http://localhost:4200/vendor.bundle.js:37214:13
onLoad@http://localhost:4200/vendor.bundle.js:53409:21
ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.bundle.js:6443:17
onInvokeTask@http://localhost:4200/vendor.bundle.js:4914:24
ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.bundle.js:6442:17
Zone.prototype.runTask@http://localhost:4200/polyfills.bundle.js:6242:28
ZoneTask/this.invoke@http://localhost:4200/polyfills.bundle.js:6496:28

推荐答案

问题出在unit-type.service.ts中.应该是:

The problem is in unit-type.service.ts. It should be:

getAllUnitTypes(): Observable<UnitType[]> {
    return this.http.get(this.unit_types_Url)
           .map(response => response.json() as UnitType[]);
}

我错过了一个事实,即没有数据对象作为返回的JSON的一部分,因此,一旦删除该对象,所有信息便会可见并正确显示在表中.

I missed the fact that there was no data object as part of the returned JSON, so as soon as that was removed all the information was visible and correctly displayed in the table.

这篇关于Angular 5 Material Table无法从服务获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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