Reputation: 11
i've been trying to build the library with angular 13 and im getting an circular dependency error:
The component 'TreeNodeChildrenComponent' is used in the template but importing it would create a cycle: D:/DATA_WINDOWS/documents/_projects/angular-tree-component/projects/angular-tree-component/src/lib/components/tree-node/tree-node.component.ts -> D:/DATA_WINDOWS/documents/_projects/angular-tree-component/projects/angular-tree-component/src/lib/components/tree-node-children/tree-node-children.component.ts -> D:/DATA_WINDOWS/documents/_projects/angular-tree-component/projects/angular-tree-component/src/lib/components/tree-node-collection/tree-node-collection.component.ts -> D:/DATA_WINDOWS/documents/_projects/angular-tree-component/projects/angular-tree-component/src/lib/components/tree-node/tree-node.component.ts
Any idea on how to solve this?
PS: If i build it with angular 11 i dont have any errors
https://stackblitz.com/edit/angular-ivy-fyvwvj?file=src/app/angular-tree-component.module.ts
UPDATE: i've ran madge to find the circular dependency and noticed that there is an issue also in the models.
Merged all models in a single file but the circular dependency continues on the components
Upvotes: 0
Views: 1051
Reputation: 11
I was able to fix th issue by merging tree-node.component.ts
, tree-node-children.component.ts
and tree-node-collection.component.ts
into a single file.
import {
Component,
ViewEncapsulation,
Input,
OnInit,
OnDestroy
} from '@angular/core';
import {
computed,
action,
reaction,
observable
} from 'mobx';
import {
TreeNode
} from '../../models/tree-node.model';
import {
TreeVirtualScroll
} from '../../models/tree-virtual-scroll.model';
import {
TreeModel
} from '../../models/tree.model';
@Component({
selector: 'tree-node-collection',
templateUrl: './tree-node-collection.component.html',
encapsulation: ViewEncapsulation.None
})
export class TreeNodeCollectionComponent implements OnInit, OnDestroy {
@Input()
public get nodes() {
return this._nodes;
}
public set nodes(nodes) {
this.setNodes(nodes);
}
@Input() public treeModel: TreeModel;
@observable public _nodes: any;
private virtualScroll: TreeVirtualScroll; // Cannot inject this, because we might be inside treeNodeTemplateFull
@Input() public templates: any;
@observable public viewportNodes: TreeNode[];
@computed public get marginTop(): string {
const firstNode =
this.viewportNodes && this.viewportNodes.length && this.viewportNodes[0];
const relativePosition =
firstNode && firstNode.parent ?
firstNode.position -
firstNode.parent.position -
firstNode.parent.getSelfHeight() :
0;
return `${relativePosition}px`;
}
public _dispose: any[] = [];
@action public setNodes(nodes: any) {
this._nodes = nodes;
}
public ngOnInit() {
this.virtualScroll = this.treeModel.virtualScroll;
this._dispose = [
// return node indexes so we can compare structurally,
reaction(
() => this.virtualScroll
.getViewportNodes(this.nodes)
.map((n: {
index: any
}) => n.index),
nodeIndexes => {
this.viewportNodes = nodeIndexes.map((i: string | number) => this.nodes[i]);
}, {
compareStructural: true,
fireImmediately: true
}
as any
),
reaction(
() => this.nodes,
nodes => {
this.viewportNodes = this.virtualScroll.getViewportNodes(nodes);
}
)
];
}
public ngOnDestroy() {
this._dispose.forEach(d => d());
}
public trackNode(node: {
id: any
}) {
return node.id;
}
}
@Component({
selector: 'tree-node-children',
encapsulation: ViewEncapsulation.None,
templateUrl: './tree-node-children.component.html'
})
export class TreeNodeChildrenComponent {
@Input() public node: TreeNode;
@Input() public templates: any;
}
@Component({
selector: 'TreeNode, tree-node',
templateUrl: './tree-node.component.html',
encapsulation: ViewEncapsulation.None
})
export class TreeNodeComponent {
@Input() public node: TreeNode;
@Input() public index: number;
@Input() public templates: any;
}
Upvotes: 0