IVY 部分的循环依赖

2024-04-14

在一个项目中,我想将我的库切换到ivy部分编译模式(角度12)。但现在遇到了一些令人讨厌的循环依赖错误:

Error 从例子

✖ Compiling with Angular sources in Ivy partial compilation mode.
An unhandled exception occurred: projects/circ/src/lib/tab-container/tab-container.component.ts:4:1 - error NG3003: One or more import cycles would need to be created to compile this component, which is not supported by the current compiler configuration.

  4 @Component({
    ~~~~~~~~~~~~
  5   selector: 'my-tab-container',
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
 42   }
    ~~~
 43 }
    ~

  projects/circ/src/lib/container/container.component.ts:4:1
      4 @Component({
        ~~~~~~~~~~~~
      5   selector: 'my-container',
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ...
     41   }
        ~~~
     42 }
        ~
    The component 'ContainerComponent' is used in the template but importing it would create a cycle: C:/projects/ng-test-projects/circular-dep-lib/projects/circ/src/lib/tab-container/tab-container.component.ts -> C:/projects/ng-test-projects/circular-dep-lib/projects/circ/src/lib/container/container.component.ts -> C:/projects/ng-test-projects/circular-dep-lib/projects/circ/src/lib/tab-container/tab-container.component.ts

很明显为什么会出现循环,但我无法找到解决方案来使其发挥作用。组件 A 内部有组件 B,而 B 内部有组件 A。它创建了类似用户可定义的 UI 之类的东西。一个组件可以包含另一组动态添加的组件,如果您愿意,可以递归。

EDIT:请考虑文档中的以下信息:https://angular.io/errors/NG3003#libraries https://angular.io/errors/NG3003#libraries一个“正常”项目可以与这个循环部门一起工作,但图书馆不行!在 stackblitz 中,所有示例都有效,甚至是我的,因为在 stackblitz 上它不是一个库。

原来的项目相当大,有一些这样的循环。这是一个简单的例子:

容器.组件.ts

import { Component, Input, OnInit } from '@angular/core';
import { UiItemLike } from '../ui-item-like';

@Component({
  selector: 'my-container',
  template: `
    <h2>Container</h2>
    <ng-container *ngFor="let item of uiItems">

      <!-- Container -->
      <!-- This recursion is working! The component itself is not "importing" from an other file -->
      <ng-container *ngSwitchCase="item.type === 'Container'">
        <my-container [uiItems]="item.uiItems"></my-container>
      </ng-container>

      <!-- Tab-Container -->
      <ng-container *ngSwitchCase="item.type === 'TabContainer'">
        <!-- Thats the circular dependency -->
        <my-tab-container [uiItems]="item.uiItems"></my-tab-container>
      </ng-container>

      <!-- Button -->
      <ng-container *ngSwitchCase="item.type === 'Button'">
        <my-button></my-button>
      </ng-container>

    </ng-container>
  `,
  styles: [``]
})
export class ContainerComponent implements OnInit, UiItemLike {
  @Input() uiItems: UiItemLike[];
  readonly type: "Container";

  constructor() {}
  ngOnInit(): void {}
}

tab-container.component.ts

import { Component, Input, OnInit } from '@angular/core';
import { UiItemLike } from '../ui-item-like';

@Component({
  selector: 'my-tab-container',
  template: `
    <h2>TabContainer</h2>
    <div>
      <h3>Fake tab 1</h3>
      <!-- Can contain more items -->
      <!-- Thats the circular dependency -->
      <my-container [uiItems]="uiItems.uiItems"></my-container>
    </div>
    
    <div>
      <h3>Fake tab 2</h3>
      <!-- ... -->
    </div>
  `,
  styles: [``]
})
export class TabContainerComponent implements OnInit, UiItemLike {
  @Input() uiItems: UiItemLike[];
  readonly type: "TabContainer";

  constructor() { }
  ngOnInit(): void {
  }
}

迁移到 Angular 12 后遇到同样的问题。能够通过启用 Ivy 解决循环 DI,只需很少的 hack。

我的问题是在链的循环 DIAL 中:ConfirmationModalComponent,其中包含动态内容OutputHtmlComponent,它支持可点击元素ClickableLabelDirective,它重用了ActionsService持有业务逻辑,信件包含链接ConfirmationModalComponent再次传入ModalService对于 open 方法,这会导致 DI 中出现所描述的循环,并在打开 Ivy“parttail”模式的情况下构建 lib 期间出现错误。

Diagram showing state before issue resolved: enter image description here

Diagram showing state after issue resolved: enter image description here

换句话说,我使用了高级组件FormPlayerComponent并注入所需的成分ConfirmationModalComponent到高水平的服务ScreenService,然后在低级服务上重用ActionService通过定期导入ScreenService服务。

因此,会稍微增加运行时的内存使用量,因为到ConfirmationModalComponent的“链接”将在服务的道具中分配,但在我的情况下,这是可以接受的决定,因为我不必重写和重新排列整个应用程序来满足新的Angular要求 - 避免递归组件,好像这在编程世界中是不自然的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IVY 部分的循环依赖 的相关文章

随机推荐