来自 API 方法 "get" 的数据源未加载到 mat-table 中

DataSource from APIs method "get" is not loaded in mat-table

我是 angularCLI 的新手。 在这种情况下,我想创建一个 table,其中数据源是从 API(假 APIs)中检索的。

这是我的组件 class:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { Blog, MyapiService } from 'src/app/services/myapi.service';

@Component({
  selector: 'app-blogs-put',
  templateUrl: './blogs-put.component.html',
  styleUrls: ['./blogs-put.component.css']
})
export class BlogsPutComponent implements OnInit {
  updateForm!: FormGroup;

  myArr = [
    {id: 11, title: 'MyTitle1', body: 'MyBody1'},
    {id: 12, title: 'MyTitle2', body: 'MyBody2'},
    {id: 13, title: 'MyTitle3', body: 'MyBody3'},
    {id: 14, title: 'MyTitle4', body: 'MyBody4'},
    {id: 15, title: 'MyTitle5', body: 'MyBody5'},
  ]

  // table
  blogs: Blog[] = [];
  displayedColumns: string[] = ['id', 'title'];
  dataSource = this.myArr;

  constructor(
    private apiS: MyapiService,
    private fb: FormBuilder
  ) { }

  ngOnInit(): void {
    this.getBlogs();

    this.updateForm = this.fb.group({
      Utitle: new FormControl('', Validators.required),
      Ubody: new FormControl('', Validators.required)
    })
  }

  pushBlog(){
    console.log(JSON.stringify(this.blogs))
  }

  getBlogs(){
    this.apiS.getBlog().subscribe(data => {
      this.blogs = data
    })
  }

  onSubmit(){
    console.log(this.updateForm.value)
  }

  injectData(){
    let newData = {
      Utitle: 'Lorem Ipsum',
      Ubody: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga repellendus accusantium, quod cupiditate deleniti soluta cum voluptate quibusdam ut laborum ipsum praesentium earum reprehenderit delectus natus adipisci suscipit eum excepturi!'
    }

    this.updateForm.setValue(newData)
  }

}

这是我的模板:

<div class="container">
  <div class="row">
    <mat-card class="full-width">
      <mat-card-title>Blogs list</mat-card-title>
      <mat-card-content>
        <table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
          <ng-container matColumnDef="id">
            <th mat-header-cell *matHeaderCellDef>Id</th>
            <td mat-cell *matCellDef="let blog">{{blog.id}}</td>
          </ng-container>
          <ng-container matColumnDef="title">
            <th mat-header-cell *matHeaderCellDef>Title</th>
            <td mat-cell *matCellDef="let blog">{{blog.title}}</td>
          </ng-container>

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

如果我为数据源分配 this.blogs(这是一个 APIs 获取数据),table 内容不会被加载。但是如果我使用本地数据 this.myArr,它会在 table 模板中成功加载。

任何帮助将不胜感激:)

根据Angular Material Table documentation,

While an array is the simplest way to bind data into the data source, it is also the most limited. For more complex applications, using a DataSource instance is recommended. See the section "Advanced data sources" below for more information.

因此,建议通过[dataSource]输入属性,值为MatTableDataSource类型


解决方案

解决方案应该如下:

blogs-put.component.html (Only provide with mat-table HTML element)

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef>Id</th>
      <td mat-cell *matCellDef="let blog">{{blog.id}}</td>
  </ng-container>
  <ng-container matColumnDef="title">
      <th mat-header-cell *matHeaderCellDef>Title</th>
      <td mat-cell *matCellDef="let blog">{{blog.title}}</td>
  </ng-container>

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

blogs-put.component.ts

import { MatTableDataSource } from '@angular/material/table';

@Component({
  selector: 'app-blogs-put',
  templateUrl: './blogs-put.component.html',
  styleUrls: ['./blogs-put.component.css']
})
export class BlogsPutComponent implements OnInit {
  ..

  dataSource: MatTableDataSource<Blog>;

  constructor(private apiS: MyapiService, private fb: FormBuilder) {
    this.dataSource = new MatTableDataSource<Blog>();
  }
  ..

  getBlogs() {
    this.apiS.getBlog().subscribe(data => {
      this.blogs = data;
      this.dataSource = new MatTableDataSource(this.blogs);
    });
  }
}

Solution on StackBlitz

已编辑:

如果您收到以下警告消息:

"Property 'dataSource' has no initializer and is not definitely assigned in the constructor."

这是因为在 tsconfig.json 中启用了 strictPropertyInitialization。因此,您可以通过在 constructorngOnInit 方法中初始化值来解决此问题。

您可以参考:.