如何在Angular Material Table中正确显示MongoDB中的JSON数据

时间:2018-01-05 16:59:34

标签: node.js mongodb angular express angular-material

欲望

我正在尝试从MongoDB中提取数据并将其显示在Angular Material Table中。

问题

虽然我能够在登录到控制台/终端时看到MongoDB调用的结果,但Chrome浏览器控制台告诉我我的JSON数据已存储到'window.json'中,我不知道如何在我的申请中引用。如果我将一些测试JSON数据硬编码到我的应用程序中并引用它而不是尝试从MongoDB调用,那么数据将填充在我的Angular Material Table中而不会出现问题。

配置

我有一个Express / Node应用程序正在调用MongoDB并通过http调用提供数据。我有一个单独的Angular应用程序,它试图对Express / Node应用程序进行http调用以使用MongoDB中的JSON并将其显示在Material Table中。所有应用程序和MongoDB都在我的计算机上运行本地(Windows 10)。 包的版本:

  • 节点9.3.0
  • TypeScript 2.6.2
  • Express 4.16.2
  • MongoDB节点驱动程序2.2.33
  • Angular 5.x

电影收藏中的MongoDB数据示例

{
        "_id" : ObjectId("56918f5e24de1e0ce2dfccc3"),
        "title" : "Once Upon a Time in the West",
        "year" : 1968,
        "imdb" : "tt0064116",
        "type" : "movie"
}
{
        "_id" : ObjectId("56918f5e24de1e0ce2dfccc4"),
        "title" : "A Million Ways to Die in the West",
        "year" : 2014,
        "imdb" : "tt2557490",
        "type" : "movie"
}
{
        "_id" : ObjectId("56918f5e24de1e0ce2dfccc5"),
        "title" : "Wild Wild West",
        "year" : 1999,
        "imdb" : "tt0120891",
        "type" : "movie"
}
{
        "_id" : ObjectId("56918f5e24de1e0ce2dfccc6"),
        "title" : "West Side Story",
        "year" : 1961,
        "imdb" : "tt0055614",
        "type" : "movie"
}
{
        "_id" : ObjectId("56918f5e24de1e0ce2dfccc7"),
        "title" : "Slow West",
        "year" : 2015,
        "imdb" : "tt3205376",
        "type" : "movie"
}

角度应用(前端)

请注意,Angular应用程序是使用Angular CLI创建的。

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { TestService } from './services/test.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatTableModule,
    MatPaginatorModule,
    HttpClientModule
  ],
  providers: [TestService],
  bootstrap: [AppComponent]
})
export class AppModule { }

test.service.ts

“serviceUrl”路径通过在后端Express应用程序中使用以下代码从MongoDB提供数据数组:

  

让movieResults = await db.collection(“movies”)。find()。toArray();

     

返回movieResults;

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Movie } from '../models/movie.model';

@Injectable()
export class TestService {

  private serviceUrl = 'http://localhost:3000/moviesdb';

  constructor(private http: HttpClient) {}

  getTest(): Observable<Movie[]> {
    return this.http.get<Movie[]>(this.serviceUrl);
  }
}

movie.model.ts

export interface Movie {
  title: string;
  year: number;
  imdb: string;
  type: string;
}

app.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, MatTableDataSource } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { DataSource } from '@angular/cdk/collections';
import { Movie } from './models/movie.model';
import { TestService } from './services/test.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'My App';
  displayedColumns = ['title', 'year', 'imdb', 'type'];
  
  movies: Movie[];
  dataSource = new TestDataSource(this._testService);

  constructor(private _testService: TestService) {}
  
  ngOnInit(){}
}

export class TestDataSource extends DataSource<any> {
  constructor(private _testService: TestService) {
    super();
  }

  connect(): Observable<Movie[]> {
    return this._testService.getTest();
  }
  disconnect() {}
}

app.component.html

<div style="text-align:center">
  <h1 id="title">
    Welcome to {{ title }}!
  </h1>
</div>

<div class="example-container mat-elevation-z8">
  <h2>Here are some movies you may be interested in:</h2>
  <mat-table #table [dataSource]="dataSource">

    <!-- Title Column -->
    <ng-container matColumnDef="title">
      <mat-header-cell *matHeaderCellDef> Title </mat-header-cell>
      <mat-cell *matCellDef="let movie"> {{movie.title}} </mat-cell>
    </ng-container>

    <!-- Year Column -->
    <ng-container matColumnDef="year">
      <mat-header-cell *matHeaderCellDef> Year </mat-header-cell>
      <mat-cell *matCellDef="let movie"> {{movie.year}} </mat-cell>
    </ng-container>

    <!-- IMDB Column -->
    <ng-container matColumnDef="imdb">
      <mat-header-cell *matHeaderCellDef> IMDB </mat-header-cell>
      <mat-cell *matCellDef="let movie"> {{movie.imdb}} </mat-cell>
    </ng-container>

    <!-- Type Column -->
    <ng-container matColumnDef="type">
      <mat-header-cell *matHeaderCellDef> Type </mat-header-cell>
      <mat-cell *matCellDef="let movie"> {{movie.type}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
  </mat-table>
</div>

参考文章

非常感谢您提供的任何指导!

1 个答案:

答案 0 :(得分:0)

材质表组件使用“dataSource”变量,因此您需要在服务响应中使用“数据源”与OnInit。

一个例子:

ngOnInit() {
this._humanService.getHumans().subscribe(
  resp => {
    this.dataSource  = new MatTableDataSource(resp);
  }, err => {
    console.log(err);
  });

}