【问题标题】:Angular: Observable service doesn't get data from apiAngular:可观察服务不从 api 获取数据
【发布时间】:2019-05-25 18:10:12
【问题描述】:

我开始使用MatTableDataSource 而不是DataSource,但从 api 获取数据时遇到问题。当我使用 booking 对象作为 const 数组时,它工作正常。但是当我想使用将从 api 获取数据的服务时,不幸的是它不起作用,我的 paginator 显示 0 个元素。下面是我的文件:

booking-table.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {MatPaginator, MatSort, MatTableDataSource} from '@angular/material';
import {BookingService} from "../../service/booking.service";

export interface BookingI {
  id: number;
  bookingDate: string;
  bookingTime: string;
  date: string;
  time: string;
  boardId: number;
  employeeId: number;
  personalData: string;
  phoneNumber: number;
  description: string;
}

@Component({
  selector: 'app-booking-table',
  templateUrl: './booking-table.component.html',
  styleUrls: ['./booking-table.component.css'],
})

export class BookingTableComponent implements OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  dataSource: MatTableDataSource<BookingI>;

  displayedColumns = ['id', 'personalData', 'phoneNumber'];

  booking: BookingI[] = [];

  constructor(private bookingService: BookingService) {

    this.bookingService.getAllBookings()
      .subscribe(value => this.booking = value);

    this.dataSource = new MatTableDataSource(this.booking);
    console.log(this.dataSource);
  }

  ngOnInit() {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }
}

booking.service.ts

import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {Observable} from "rxjs";
import {Booking} from "../model/booking";
import {catchError} from "rxjs/operators";

@Injectable({
  providedIn: 'root'
})
export class BookingService {

  private httpOptions = {
    headers: new HttpHeaders({'Content-Type': 'application/json'})
  };

  constructor(private http: HttpClient) {
  }

  getAllBookings(): Observable<Booking[]> {
    const url = 'http://localhost:8080/bookings';
    return this.http.get<Booking[]>(url)
      .pipe(catchError(this.handleError));
  }

  private handleError(error: any): Promise<any> {
    console.error('Error', error); // for demo purposes only
    return Promise.reject(error.message || error);
  }
}

booking-table.component.html

<div class="mat-elevation-z8">
  <table mat-table [dataSource]="dataSource" matSort>

    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Id</th>
      <td mat-cell *matCellDef="let booking">{{booking.id}}</td>
    </ng-container>

    <ng-container matColumnDef="personalData">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Dane klienta</th>
      <td mat-cell *matCellDef="let booking">{{booking.personalData}}</td>
    </ng-container>

    <ng-container matColumnDef="phoneNumber">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Nr telefonu</th>
      <td mat-cell *matCellDef="let booking">{{booking.phoneNumber}}</td>
    </ng-container>

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

  <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>

有人能写出我的 get 方法有什么问题吗?需要明确的是,当我使用 DataSource 时它工作正常,但是当我使用 MatTableDataSource 服务获取方法时不起作用。

【问题讨论】:

  • this.booking异步填充。如果它是同步的,服务将返回一个 Observable。它会直接返回数组。它返回一个 observable,以便它可以在很久以后通知您预订最终已由服务器发送。因此,您只能确定预订在传递给 subscribe() 的回调函数内部。顺便说一句,由于它是一个 array 的预订s,因此您最好将其命名为 bookings,而不是 booking
  • 好的,你知道我应该检查什么吗?或者我应该在哪里寻找问题?我在浏览器中没有收到任何错误,我也不知道是什么问题。
  • 好吧,我已经在我之前的评论中描述了你做错的事情以及如何解决它。你读过吗?那条评论中有什么你不明白的地方?
  • 我知道 this.booking 是异步填充的,我应该同步填充它。
  • 没有。您不能使 AJAX 调用同步。再次阅读我的评论:您只能确定预订在传递给 subscribe() 的回调函数中。所以这就是你必须初始化数据源的地方,而不是在你发送请求之后,因为那时还没有收到预订。

标签: angular typescript angular-material observable angular7


【解决方案1】:

一个好的做法是仅将constructor 用于注入,并使用钩子方法,例如ngOnInit 用于其余部分。尝试用类似的东西替换你的代码:

constructor(private bookingService: BookingService) {
}

ngOnInit() {

    this.bookingService.getAllBookings().subscribe(value => {
        console.log(value);
        this.dataSource = value;
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
    });
}

【讨论】:

  • 当我移动它时它可以正常工作:this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; 在订阅括号内。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2018-09-16
  • 2020-01-29
  • 1970-01-01
  • 2019-05-21
  • 2018-02-23
相关资源
最近更新 更多