首页 > 解决方案 > 具有不同返回类型的通用数据服务

问题描述

我创建了这个通用数据服务,如下所示:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { environment } from '../../../environments/environment';
import { Resource } from '../models/resource';

const API_URL = environment.apiUrl;

@Injectable()
export class DataService<T extends Resource> {

  constructor(
    private httpClient: HttpClient,
    private endpoint: string) {}

  public create(item: T): Observable<T> {
    return this.httpClient
      .post<T>(`${API_URL}/${this.endpoint}`, item);
  }

  public update(item: T): Observable<T> {
    return this.httpClient
      .put<T>(`${API_URL}/${this.endpoint}/${item.id}`, item);
  }

  read(id: number): Observable<T> {
    return this.httpClient
      .get(`${API_URL}/${this.endpoint}/${id}`)
      .map(response => response as T);
  }

  list(): Observable<T[]> {
    return this.httpClient
      .get(`${API_URL}/${this.endpoint}`)
      .map(response => response as T[]);
  }

  delete(id: number) {
    return this.httpClient
      .delete(`${API_URL}/${this.endpoint}/${id}`);
  }
}

然后我创建了一个CategoryService来扩展它:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { DataService } from './data.service';
import { Category } from '../models/category';

@Injectable()
export class CategoryService extends DataService<Category> {

  constructor(httpClient: HttpClient) {
    super(
      httpClient,
      'categories'
    );
  }

}

所以现在我拥有了该服务可用的所有 CRUD 方法。从那以后,我创建了许多其他服务,每个都扩展了DataService. 问题是,我遇到了一个与返回类型不匹配的 API 端点。例如,端点“/categories”,我的数据服务期望所有端点返回一个实体,对于类别,即Category

import { Resource } from "./resource";

export class Category extends Resource {
    name: string
}

但是,category API 有一个端点,它返回Questions列表。其路径是“/categories/2/questions”。我怎样才能让它与我的通用数据服务一起使用?我假设答案是我不能,但是必须有办法解决这个问题,也许是在每次调用而不是实例化时提供模型类型?

任何帮助,将不胜感激。我希望这是有道理的。

标签: angular

解决方案


听起来这条新路线并不通用。我认为CategoryService应该是实现新方法的类。

export class CategoryService extends DataService<Category> {

  constructor(httpClient: HttpClient) {
    super(
      httpClient,
      'categories'
    );
  }

  getQuestions(id: number): Observable<Question[]> {
    return this.httpClient
      .get<Question[]>(`${API_URL}/${this.endpoint}/${id}/questions`);
  }
}

您可以通过将endpointhttpClient访问修饰符更改为protected


推荐阅读