【问题标题】:Angular Unable to Init Service (HttpClient) in a ClassAngular 无法在类中初始化服务(HttpClient)
【发布时间】:2018-12-24 08:01:55
【问题描述】:

我想通过从类中创建数据访问对象来隔离 http 交互,以便在组件中我可以简单地获取如下数据:

// dashboard.component
import { AppUser } from './appuser.service'

export class DashboardComponent implements OnInit {
  user: AppUser = new AppUser();

  constructor() { }

  ngOnInit() {
    let id = JSON.parse(window.localStorage.getItem('session')).userId;
    this.user.find(id) // 'find' is from base class
      .subscribe(
        // handle user data
      );
  }
}

我已经定义了一个基类和一个像这样的子类:

// base-resource.service
import { HttpClient } from '@angular/common/http';
...
export class BaseResource {
  private fullpath: string;
  protected http: HttpClient;

  constructor (path: string) {
    this.fullpath = path;
  }

  find (id): Observable<Object> {
    return this.http.get(this.fullpath + '/' + id); // this line throws Error!
  }
}

// app-user.service
...
export class AppUser extends BaseResource {
  constructor(data?) {
    super('api/appusers');
  }
}

但是这会产生错误:ERROR TypeError: Cannot read property 'get' of undefined 来自基类函数。

我的“AppUser”实例显然是从“BaseResource”继承find,但find 正在获取“Ap​​pUser”实例,因为thishttp 的值不可用。我尝试将http 声明为公共和私有以及受保护,但这没有任何效果。我想我错过了一些关于如何扩展类的大图。

尽可能具体地,我认为我的问题是当函数需要访问基类的上下文时,如何将它们抽象为基类。

(使用 Angular 6.0.4)

编辑 我更新了标题,因为很明显这是在类中实例化 HttpClient 服务的问题。

【问题讨论】:

  • 是抛出编译错误还是runtme错误?从我所见,你永远不会在任何地方初始化 http,所以它是未定义的。
  • 该错误是运行时错误。我在 BaseResource 中导入 HttpClient。它不是通过构造函数注入的,因为(我认为)这会阻止“更新”实例。不过,在这一点上我当然可能是错的。
  • 是的,导入它不会创建实例,它只是类型安全所需要的。您是否需要直接注入BaseResource,或者它总是一个扩展BaseResource 的类?
  • 如果我还需要实例化它,也许stackoverflow.com/questions/49507928/… 有我的答案。我的意图是永远不要直接使用 BaseResource。

标签: javascript angular typescript


【解决方案1】:

报错是因为什么都没有实例化HttpClient,所以来使用的时候是未定义的。

您应该将HttpClient 注入AppUser,并通过构造函数将其传递给BaseResource

export class AppUser extends BaseResource {
  constructor(HttpClient http) {
    super(http, 'api/appusers');
  }
}

在 base-resource.service 中

import { HttpClient } from '@angular/common/http';
...
export class BaseResource {
  private fullpath: string;
  protected http: HttpClient;

  constructor (httpClient: HttpClient, path: string) {
    this.fullpath = path;
    this.http = httpClient;
  }

  find (id): Observable<Object> {
    return this.http.get(this.fullpath + '/' + id); // this line throws Error!
  }
}

【讨论】:

  • 我在传递它时快速通过并能够访问http;它肯定缺少实例化。但是,在每次调用此类实例时传入“HttpClient”实例在某种程度上似乎是“错误的”。如果我需要十几个服务,或者如果我需要添加一个服务,似乎我必须更新每个调用,这是我想通过抽象来避免的。
猜你喜欢
  • 2015-09-15
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2017-02-23
  • 2017-06-06
  • 1970-01-01
相关资源
最近更新 更多