【问题标题】:Avoiding circular dependency injection when two directives check for the presence of each other?当两个指令检查彼此是否存在时避免循环依赖注入?
【发布时间】:2021-11-07 23:31:28
【问题描述】:

假设我有一个组件<app-card>,它将一些信息封装到屏幕上的一个区域中。我想根据需要使用指令单独添加功能。例如,如果我希望卡片有一个复选框,我可以简单地将 CardIsCheckableDirective 应用于组件,如下所示:

<app-card [appCardIsCheckable]></app-card>

现在说我还希望这个组件是可拖放的,使用 mousedown 和 mouseup 事件,所以我创建了一个CardIsDraggableDirective,它也可以应用于组件宿主:

<app-card [appCardIsCheckable] [appCardIsDraggable]></app-card>

很遗憾,checkable 指令和 draggable 指令的实现细节发生冲突,because of a need to distinguish between the click event and the mousedown/mouseup events,因此可以想象 checkable 指令在可拖动指令存在时会修改其行为,反之亦然。

CardIsCheckableDirective 可以像这样注入CardIsDraggableDirective

public constructor(@Optional() @Host() public cardIsDraggable: CardIsDraggableDirective) {}

如果cardIsDraggable 属性不为空,则该指令知道另一个指令也绑定在宿主组件上,它可以修改它的功能。但是,一旦您执行反向注入,通过将CardIsCheckableDirective 提供给CardIsDraggableDirective,Angular 就会抛出以下错误:

NG0200: Circular dependency in DI detected for CardIsCheckableDirective. Find more at https://angular.io/errors/NG0200

Angular 网站上的这篇支持文章暗示你的架构不正确,建议重构你的服务结构以打破循环依赖。然而,这是两个指令,它们都只需要知道相反的指令是否存在于主机组件上;我认为这是一个合理的要求。

如何在保留所需功能的同时打破这种循环依赖循环?

【问题讨论】:

  • 你能修改你的问题以包含指令的实现吗?
  • @John 指令的实现细节与问题无关。
  • 我不同意,共享服务可能是也可能不是一个选项,具体取决于实现。 “可惜checkable指令和draggable指令的实现细节冲突了”,我想知道如何。

标签: angular


【解决方案1】:

您可以使用在单独文件中声明的注入令牌。鉴于您只检查这些指令是否存在,并且您不需要与实例本身交互(在这种情况下,您需要接口(在单独的文件中,以避免循环依赖)。

const DRAGGABLE = new InjectionToken('DRAGGABLE');
const CHECKABLE = new InjectionToken('CHECKABLE');

你可以像这样修改你的指令:

@Directive({
  // ...
  providers: [
    {
      provide: CHECKABLE,
      useExisting: CardIsCheckableDirective,
    }
  ]
})
public class CardIsCheckableDirective {
  constructor(@Inject(DRAGGABLE) @Optional() @Host() public draggable: any) {}
}
@Directive({
  // ...
  providers: [
    {
      provide: DRAGGABLE,
      useExisting: CardIsDraggableDirective,
    }
  ]
})
public class CardIsDraggableDirective {
  constructor(@Inject(CHECKABLE) @Optional() @Host() public checkable: any) {}
}

如果您将两个注入令牌放在同一个文件中,它也可能会起作用,因为这不会导致循环依赖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-03
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多