我有一个问题介绍给这里。
我有一个ParentComponent
,它有一个子ChildComponent
,而在它里面有一个ParentComponent
,所以这里有一个循环。
这是我面临的错误:
✖ 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
时,这个错误就消失了,但是在这种情况下,我们失去了向后兼容性!
官方医生说:
将相互引用的类移动到同一个文件中,以避免它们之间的任何导入。区块报价
这是可行的,但这确实是一种丑陋的做法!此外,我们有很多组件,我们只是不能这样做!
你能帮帮我吗?!
发布于 2021-11-23 09:40:08
好了,在网上看了一遍,我终于自己解决了!
我使用了这篇文章所建议的动态方法:
您可以在stackblitz中看到我的解决方案。
这里我必须再次提到,这个问题(NG3003)只发生在角库和partial
compilationMode中。
所以我前面提到的那篇文章不是一个完整的解决方案,也不是一个有用的例子。我添加的是一个名为ComponentStructure
的接口
export interface ComponentStructure {
type: string;
content: {
textContent: string;
components: ComponentStructure[];
};
}
和components
输入到父组件和子组件:
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
类如下:
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
并不适用于我,我不得不这样做。
如果你对此有更好的想法,请在评论中告诉我。
发布于 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添加到组件选择器中:
https://stackoverflow.com/questions/70047200
复制相似问题