0

问题

在过去的一周里,我一直在为 Angular2 项目开发身份验证库。这个库主要是基于服务的,几乎可以直接开箱即用。您唯一需要做的就是将它包含在您的应用程序中并为其设置配置对象。

这里的主要服务是 AuthService。此服务包括 Http 和另一个自定义服务。问题是这两个依赖项都需要开发人员指出这些类的提供者。我不确定我是否做对了,但我已经看到了需要导入 HTTP_PROVIDERS 才能使用 Http 的解决方案。

因此,如果我将 AuthService 作为依赖项导入,我仍然需要同时导入 HTTP_PROVIDERS 和自定义服务以使 DI 工作。

bootstrap(App, [AuthService, HTTP_PROVIDERS, CustomService]);

这打乱了我对模块易于包含的想法。我只想提供导入 AuthService。

到目前为止我尝试过的事情

首先,我开始阅读一些关于 Angular2 中 DI 的博客。你们中的大多数人可能都知道 Thoughtram 在提供这些信息方面做得很好(也是 EggHead.io)。我最终阅读了这两个帖子:

http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html http://blog.thoughtram.io/angular/2015/09/17/resolve-service -dependencies-in-angular-2.html

阅读它们后,我认为解决方案很简单,但一段时间后似乎并非如此。我想我在这里错过了重点。还在以 DI 为主要卖点的 Spring boot 中工作,我没有设法让它工作似乎很奇怪(可能是 Angular2 仍处于 Alpha 阶段且文档稀缺的事实)。

我尝试过的解决方案

所以我尝试了一些我想出的解决方案,但都没有奏效。

提供一个常数

我的第一个想法是查看 HTTP_PROVIDERS 常量,它就像 Http 依赖项的提供者。我最终查看了它的源代码。

https://github.com/angular/angular/blob/b0009f03d510370d9782cf76197f95bb40d16c6a/modules/angular2/http.ts#L151

在那之后,我认为我最好尝试为我自己的班级实现这一点。

export const AUTH_PROVIDERS: any[] = [
  provide(AuthService, {
    useFactory: (http, customService) => new AuthService(http, customService),
    deps: [Http, CustomService]
  })
  ,
  provide(CustomService, {
    useFactory: () => new CustomService(),
  })
];

完成后,我将它包含在我的引导函数中,之后我遇到了另一个错误。

Token must be defined!

我花了一些时间试图找出问题所在,但我没能做到。

使用注释

Angular2 中的一项新功能是注解。所以我希望其中之一能够帮助我解决我的问题。和似乎不是我需要的@Component@View我相信他们更多地关注功能性对象的视觉方面(因为视图不是我需要的东西,而是强制性的)。

下一部分看起来很奇怪,因为我找不到这是否是注释(可能不是......)。我试着给@Provider 一个机会。这导致了以下“可能的”解决方案。

@Provider({
  token: 'AuthService',
  useFactory: (http, customService) => new AuthService(http, customService)
  ...
})
export class AuthService{
  constructor(http: Http, customService, CustomService){...}
}

这只是给了我另一个错误,但这次它是由 Typescript 编译器抛出的。

error TS2348: Value of type 'typeof Provider' is not callable. Did you mean to include 'new'?

无论如何,有人可以帮我解决这个问题。上述解决方案之一是朝着正确方向迈出的一步,还是我做错了什么?

提前致谢。

4

1 回答 1

2

好吧,我发现了问题,但这是我以前没有想到的(可能是因为我主要使用 Java 工作)。Typescript(最终是 JavaScript)不喜欢的一件事是引用一个在您需要的代码下方定义的类。我想这就是“必须定义令牌的地方!” 错误来自。无论如何切换代码片段解决了这个问题。

export class AuthService{...implementation...}

export const AUTH_PROVIDERS : any[] = [
  HTTP_PROVIDERS,
  provide(AuthService, {
    useFactory: (http, customService) => new AuthService(http, customService),
    deps: [Http, CustomService]
  }),
  provide(CustomService, {
    useFactory: () => new CustomService()
  })
];

希望这可以在将来对其他人有所帮助。

于 2015-11-23T12:26:26.750 回答