首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NG3003:库中的角12循环依赖-常春藤部分compilationMode

NG3003:库中的角12循环依赖-常春藤部分compilationMode
EN

Stack Overflow用户
提问于 2021-11-20 15:15:13
回答 2查看 1.6K关注 0票数 3

我有一个问题介绍给这里

我有一个ParentComponent,它有一个子ChildComponent,而在它里面有一个ParentComponent,所以这里有一个循环。

这是我面临的错误:

代码语言:javascript
运行
复制
✖ Compiling with Angular sources in Ivy partial compilation mode.
ERROR: projects/api/src/lib/api.component.ts:3: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.

The component 'ParentComponent' is used in the template but importing
it would create a cycle:
 /lib/child/child.component.ts -> /lib/parent/parent.component.ts -> /lib/child/child.component.ts

此错误仅在角库中发生。因此,正如您所看到的,在stackblitz示例中没有问题,这只是一个演示。

当在库的"compilationMode": "full"文件中设置tsconfig.lib.prod.json时,这个错误就消失了,但是在这种情况下,我们失去了向后兼容性!

官方医生说:

将相互引用的类移动到同一个文件中,以避免它们之间的任何导入。区块报价

这是可行的,但这确实是一种丑陋的做法!此外,我们有很多组件,我们只是不能这样做!

你能帮帮我吗?!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-23 09:40:08

好了,在网上看了一遍,我终于自己解决了!

我使用了这篇文章所建议的动态方法:

具有动态嵌套分量的角圆依赖项

您可以在stackblitz中看到我的解决方案。

这里我必须再次提到,这个问题(NG3003)只发生在角库partial compilationMode中。

所以我前面提到的那篇文章不是一个完整的解决方案,也不是一个有用的例子。我添加的是一个名为ComponentStructure的接口

代码语言:javascript
运行
复制
export interface ComponentStructure {
  type: string;
  content: {
    textContent: string;
    components: ComponentStructure[];
  };
}

components输入到父组件和子组件:

代码语言:javascript
运行
复制
import { Component, Input } from '@angular/core';
import { Base } from '../base';
import { HtmlComponent } from '../child-node.directive';
import { ComponentStructure } from '../component-structure';

@HtmlComponent({ map: ['lib_parent'] })
@Component({
    selector: 'lib-parent',
    templateUrl: './parent.component.html',
  ],
})
export class ParentComponent extends Base {
  @Input() count = 3;
  @Input() set components(_components: ComponentStructure[]) {
    this.childNodes = _components;
  }
  public textContent: string = '';

  constructor() {
    super();
  }

  set content(content: any) {
    this.textContent = content.textContent;
    this.components = content.components;
  }
}

另外,我更改了Base类如下:

代码语言:javascript
运行
复制
import { Directive, QueryList, ViewChildren } from '@angular/core';
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
import { ChildNodeDirective } from './child-node.directive';
import { ComponentStructure } from './component-structure';

@Directive()
export abstract class Base {
  // These are elements that the template will render into the directive
  @ViewChildren(ChildNodeDirective) protected children?: QueryList<any>;
  public childNodes: ComponentStructure[] = [];
  private childrenLoaded = false;

  ngAfterViewInit(): void {
    interval(10)
      .pipe(take(5))
      .subscribe(() => {
        if (!this.childrenLoaded && this.children) {
          this.children.forEach((child: ChildNodeDirective) => {
            child.load();
          });
          this.childrenLoaded = true;
        }
      });
  }
}

我不喜欢的是interval,这是一个棘手的部分。但是在最初的答案中使用的AfterContentChecked并不适用于我,我不得不这样做。

如果你对此有更好的想法,请在评论中告诉我。

票数 0
EN

Stack Overflow用户

发布于 2022-10-02 23:38:13

你好,这是老话题,但我找了很长时间的一个解决方案。我找到了你的解决方案但没能说服我。所以这就是我的解决方案。

正如您在响应中提到的,问题是导入父级的子代,如下图所示。问题循环deps模式

在html中,导入是由所使用的yo标记隐式的。

这个概念并不是说角度,它是一个已知成分的导入。这一点:在chilComponent.ts中:

@ parentComponentType;@ViewChild('id',{read: ViewContainerRef,静态: false})容器: ViewContainerRef;ngAfterViewInit() { const formGen =ngAfterViewInit formGen.setInput('someInputToSet',someValue);}

在ChildComponent.html替换中

<parent></parent>

通过

<div #id></div>

这段代码

它是为了传递组件,在输入parentComponentType中传递并在div中创建它,这是您以前所替换的。

在parent.html中,将输入指令parentComponentType添加到组件选择器中:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70047200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档