【问题标题】:Angular 9 do abstract classes for services need the @injectable decorator?Angular 9 服务的抽象类需要@injectable 装饰器吗?
【发布时间】:2020-10-14 17:55:53
【问题描述】:

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

我的应用程序上的一切正常。

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

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

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

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

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

【问题讨论】:

  • 检查这个:hackmd.io/@alx/S1XKqMZeS
  • @Chellappan 谢谢你解释了很多。我认为从我读到的内容是由于常春藤,对吧?
  • 是的@Jimmy Kane
  • 请随时使用此内容发布答案。我很乐意接受它:-)
  • 由于您已经为您的旧问题添加了答案,因此我支持您的答案。

标签: angular typescript angular9


【解决方案1】:

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

For More Details

Link2

【讨论】:

    【解决方案2】:

    添加一些附加信息:

    Ivy 中的一个关键概念是局部性,因此为了编译或重新编译组件,编译器不再扫描整个代码库——只重新编译组件;并且,组件的所有行为都必须在编译的类中捕获。 The link provided in other answers provides more details on the "why".

    基类(无论是否抽象)具有 Angular 装饰器(@Directive@Component@Injectable@NgModule)的“Ivy 新手”要求仅适用于基类使用 Angular 特性的情况,例如如果他们实现了像OnInitOnDestroy 这样的生命周期接口。如果你的基类不使用 Angular 特性,你就不需要 Angular 装饰器。

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

    【讨论】:

    • 嘿,谢谢 Crimbo。这确实是一个很好的上下文
    【解决方案3】:

    您的问题与未装饰父模式有关。

    我无法在没有看到您的代码的情况下对其进行具体评论,但总的来说,使用聚合而不是继承可能会更好。换句话说,将您的基类重新设计为服务,然后将其注入派生类。

    【讨论】:

    • 好建议!谢谢你现在大部分时间已经这样做了
    【解决方案4】:

    这里有一些关于这个的附加信息:

    • 我们了解 Ivy 对类装饰器等的要求。

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

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

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

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

    但是……

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

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

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

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

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

    所以在这里扩展答案:

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

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

    【讨论】:

    • 我一直在使用具有角度特征的摘要,并且在任何地方都没有声明
    • 如果你阅读了文档,你就不能再这样做了。使用角度特征的类必须有一个装饰器。你确定你是用 Angular 10 编译的吗?
    • 抱歉我的评论不好。我的意思是我没有在模块中声明类。 >这意味着它必须在一个模块中声明,它禁止声明抽象类。我想我指的是本地模块,但你指的是依赖项?或者我完全理解错误的帮助?
    猜你喜欢
    • 2020-09-25
    • 2022-11-14
    • 1970-01-01
    • 2021-07-03
    • 2019-01-18
    • 2019-12-21
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多