【问题标题】:TypeScript Circular DependencyTypeScript 循环依赖
【发布时间】:2019-12-09 17:11:53
【问题描述】:

我有 2 个班级,A 级和 B 级。 B 类扩展了 A 类,以便我可以访问 A 类的实例和服务。B 类具有一些我将在 A 类中使用的功能。当我实现它时,出现了循环依赖错误,现在我收到一个浏览器错误消息:

“tslib.es6.js:25 Uncaught TypeError: Object prototype may only be an Object or null: undefined”。


import { BuyerCardComponent} from './buyer-card.component'

export class BuyerCardExtended extends BuyerCardComponent{
  func a(){
    do_something;
  }
}

import { BuyerCardExtended } from './buyer-card-extended'

class BuyerCardComponent {
constructor(private buyerCardExtended: BuyerCardExtended){}
  func b(){
    this.buyerCardExtended.a()
  }
}

检测到循环依赖中的警告: src/app/components/buyer/products/buyer-card/buyer-card.component.ts -> src/app/components/buyer/products/buyer-card/buyer-card-extended.ts -> src/app/ components/buyer/products/buyer-card/buyer-card.component.ts

浏览器:

"tslib.es6.js:25 Uncaught TypeError: Object prototype may only be an Object or null: undefined"

【问题讨论】:

  • 把它们放在同一个文件中
  • B 类扩展 A 类,以便我可以访问 A 类的实例和服务”听起来您正在使用继承进行代码共享。记住:composition over inheritance - 如果你只是想分享功能,那么模块化并包含它。扩展其他对象来执行此操作会污染您的架构,并导致您做出以后可能会后悔的设计决策。
  • 将两个类共享的逻辑分离到第三个类中,以及每个类的不同之处。您不能将扩展类作为另一个依赖项。编译器将如何尝试解决这个问题?他需要创建一个BuyerCardExtended 才能创建BuyerCardComponent,但还需要BuyerCardComponent 来创建BuyerCardExtended。你创造了一个先有鸡还是先有蛋的问题。
  • 实际上,在阅读您的下一句话时(我写第一篇评论时还没有),这是一个完美的例子,说明 为什么 代码共享的继承是错误的:“B 类有一些我将在 A 类中使用的功能" 你需要有 A extends BB extends A 才能工作...工作都是在概念层面或在实施方面。
  • @BunyaminCoskuner,它们之前在同一个文件中,逻辑在一个大函数中,将圈复杂度增加到 20+(编码标准限制为 20)。因此,决定拆分逻辑

标签: angular typescript extends


【解决方案1】:

这个场景背后的主要原因是这个序列:当你执行Class A时,它会自动导入Class B。在Class B 中,您导入Class A,它会再次自动导入Class B。这个序列一次又一次地发生,最终导致循环依赖。

第一个解决方案是创建另一个类并将所有依赖项导入其中。或者,如果您只想在两个类之间共享一些函数和变量,我建议您使用共享服务并在其中声明所有函数。然后,将服务导入您的组件或类。

【讨论】:

  • 那么,我将创建另一个类并将核心依赖项导入到这个类中,在其他类中,我将实例化这个基类并访问这些依赖项?
  • 这真的取决于你的目标是什么,但在这种特殊情况下,你所说的会奏效。
【解决方案2】:

如果要从父类调用子类方法,请使用@ViewChild 装饰器。

import { BuyerCardExtended } from './buyer-card-extended'

class BuyerCardComponent implements AfterViewInit {
@ViewChild(BuyerCardExtended) childCmp : BuyerCardExtended;
constructor(){}
ngAfterViewInit(){
  func b(){
    this.childCmp.a(); }
  }
}

另见stackoverflow thread

【讨论】:

  • BuyerCardExtended 扩展了这个类,会不会又是循环依赖了
  • 不应该。 ViewChild 不实例化类的对象。它创建一个视图查询。我相信它应该工作。试试看,让我们知道。
猜你喜欢
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 2014-09-22
  • 2014-07-29
  • 1970-01-01
  • 2015-01-25
相关资源
最近更新 更多