2

升级到 Angular 9 后,我的一些服务扩展的抽象类会自动使用@injectableAngular 9 迁移指南中所写的修饰。

我的应用程序上的一切都有效。

但是我不明白为什么必须装饰抽象类,因为扩展它们的具体类确实具有@injectable装饰器。

我还阅读了这个问题Angular library module injection service with abstract class并建议删除@injectable从摘要中删除。

那么我应该删除装饰器吗?

这只是将装饰器添加到我的摘要中的 Angular“错误”吗?

此外,我注意到@directive装饰器已添加到用于实现组件的其他抽象类中。

4

4 回答 4

5

直到 Angular 8 装饰器对于指令和组件的基类都是可选的。使用最新的角度版本(9)。类需要装饰器。

更多细节

链接2

于 2019-12-08T17:49:46.513 回答
1

Your problem is related to the Undecorated Parent pattern.

I cannot comment on your code specifically without seeing it, but as a general point it may be better to use aggregation rather than inheritance. In other words redesign your base class as a service, which is then injected into the derived class.

于 2020-10-12T11:02:58.330 回答
1

要添加一些附加信息:

Ivy 中的一个关键概念是局部性,因此为了编译或重新编译组件,编译器不再扫描整个代码库——只重新编译组件;并且,组件的所有行为都必须在编译的类中捕获。其他答案中提供的链接提供了有关“为什么”的更多详细信息

基类(抽象或非抽象)具有 Angular 装饰器(@Directive, @Component, @Injectable, @NgModule)的“Ivy 新手”要求仅适用于基类使用 Angular 功能的情况,例如,如果它们实现了生命周期接口,如OnInitor OnDestroy。如果你的基类不使用 Angular 特性,你就不需要 Angular 装饰器。

在 Angular 9 中,这个要求是可选的;但不要从 CLI 升级放置的基类中删除装饰器,因为这个要求在 Angular 10 中是非可选的。

于 2020-07-04T16:38:32.307 回答
0

此处处理此问题的一些附加信息:

  • 我们知道 Ivy 对类装饰器等的要求。

但是,这是我刚刚经历的一个序列,这似乎意味着如果该类使用角度特征(输入等),则无法为指令创建抽象基类。需要进行重构。

  • 有一个组件使用的基类。它是抽象的并使用角度特征。
  • 进行了升级,看到添加了空指令。
  • 不会编译。指令中需要的元数据 obj。
  • 查看文档(Angular.io),说用空白选择器添加数据。

我做了所有这些,即使 TS lint 为空白选择器哭泣,我用 tslint:disable... 关闭了它。

...虽然不再显示为 lint 错误,但现在显示为构建错误(实际上是说,“请添加它!”)。所以我添加了一个选择器,它带有一些永远不会被使用的概念,因为该类是抽象的。

但...

...该类以前未添加到模块中。我没有编写原始代码,并且很惊讶这从未出现在 --prod 构建中,但是阅读了以前的图形引擎,我发现它是宽容的,因为它具有全局可见性。但是 Ivy 没有,它是独立编译的,所以你需要我放的装饰器,然后就出现了 no-module 错误。所以我将它添加到相关模块中。

...没有利润。“不能将抽象构造函数添加到非抽象构造函数。” 换句话说,我猜你不能在模块中声明一个抽象类(至少,不是通常的“只是将它添加到声明中”的方式)。

所以最终,没有考虑重构相当复杂的组件层次结构,我只是从类定义中删除了抽象。

然而,这个序列确实邀请了直接使用该基类并通过其选择器的机会。这不是框架强迫你进入的好状态。

我摆弄了一下,但找不到直接绕过它的方法。

所以在这里扩展答案:

“如果抽象类使用角度特性,你似乎不能拥有它们,因为如果你使用这些特性,你必须在类上使用角度装饰器,这意味着它必须在模块中声明,这禁止声明抽象类。”

(即使文档说“你可以将选择器留空”,除非你想调整你的规则,似乎你不能)。

于 2020-09-08T17:05:01.017 回答