【发布时间】:2018-06-28 23:03:29
【问题描述】:
这个问题通常是关于扩展或替换组件库中的组件。我将使用一个例子。我们有一个跨项目使用的组件库,其中包含许多 UI 组件和指令。这些组件可以即时翻译。小部件将翻译服务注入其中,程序员指定他们想要翻译的键。这里一切顺利。
假设这个基础翻译服务有方法 getTranslation() 来保持简单。
对于我们的大多数产品,基本翻译服务都是开箱即用的。对于其他人,他们想使用不同的版本。我的第一个想法是定义一个接口,基础翻译/其他项目的服务实现它(对于 Spring Java 人来说很正常)。我正在阅读角度样式指南,上面写着“考虑使用类而不是接口”。我挖了一会儿才明白为什么(因为我的背景是 Java),这是有道理的,因为 Angular DI 注入的工作方式似乎不同https://github.com/angular/angular/issues/19632。
因此,作为测试,在示例项目中,我创建了一个子类。
import { Injectable } from '@angular/core';
import { BaseTranslationService } from './base-translation.service';
@Injectable()
export class MyTranslationService extends BaseTranslationService {
constructor() {
super();
}
getTranslation(bundle: string, key: string, params?: any[]): string {
let translation = super.getTranslation(bundle, key, params);
return translation + ' from subclass';
}
}
虽然基础翻译服务上还有许多其他方法,但我只是想用一些沙盒内容覆盖上面的方法。
最后,在消费项目中,我知道不再提供 BaseTranslationService 而是提供新的:
providers: [ MyTranslationService, etc ]
这不起作用。我在期望 BaseTranslationService 的所有组件上都收到此错误:
NullInjectorError:没有 BaseTranslationService 的提供者!
DI 似乎不理解 MyTranslationService 是否适用于 BaseTranslationService。
这应该有效吗?我是否设置不正确?我是否误解了风格指南?
【问题讨论】:
-
您是否用
@Injectable注释了export class MyTranslationService extends BaseTranslationService {?如果它对您有用,我会将其发布为答案! :) :D -
我认为@Aravind 是对的。您需要用
@Injectable装饰 MyTranslationService 并从 BaseTranslationService 中删除@Injectable -
这个问题缺少stackoverflow.com/help/mcve .. 目前还不清楚这些类来自哪里以及它们是如何使用的。没有将 deps 注入其构造函数的类不需要 @Injectable。
-
@Aravind 我没有可注入的装饰器,但我现在有/更新了上面的示例,但仍然是同样的错误。 LLai - 我无法从 BaseTranslationService 中删除可注入的内容,因为在很多情况下我想按原样注入它。
-
@Scott 你也可以添加
BaseTranslationService的代码吗?建议您创建一个有效的plunker或stackblitz
标签: angular dependency-injection extends