-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Hi! Thank You very much for all of your work ;)
when I was using ng-diagram in a popup dialog in fullscreen mode, I get across en unhandleded error about that:
`app.html:6 Error unregistering model listener: Error: [ngDiagram] Library engine not initialized yet.
To fix this, wait for initialization to complete using one of these methods:
• Use "isInitialized" signal from NgDiagramService
• Use "diagramInit" event handler passed to NgDiagramComponent
Documentation: https://www.ngdiagram.dev/docs/guides/model-initialization/#waiting-for-initialization
at _FlowCoreProviderService.provide (ng-diagram.mjs:6141:31)
at get flowCore (ng-diagram.mjs:6436:34)
at _NgDiagramModelService.ngOnDestroy (ng-diagram.mjs:10108:12)
at executeOnDestroys (debug_node.mjs:7483:32)
at cleanUpView (debug_node.mjs:7379:9)
at destroyViewTree (debug_node.mjs:7323:17)
at destroyLView (debug_node.mjs:7353:5)
at removeLViewFromLContainer (debug_node.mjs:9327:9)
at Module.ɵɵconditional (debug_node.mjs:22036:17)
at App_Template (app.html:6:3)`
When I close a dialog. So we just destroy the component which has an ng-diagram component instance inside.
What is funny it only throws when we have injected NgModelService inside the compononent. Yeah and I need the modelService for later use to change the diagram data inside.
Also I have struggled with auto zooming to fit after modelService.addNodes() method, it somhow is async and it calculates the zoom and viewport while new nodes are still not added. - but maybe it's a different issue :)
code snippets:
app.html
`<button (click)="closeDiagram()">Close diagram
diagram.html
@if (model()){ <ng-diagram [model]="model()" [nodeTemplateMap]="nodeTemplateMap" [config]="config" /> }
diagram.ts
`import {
Component,
inject,
effect,
signal,
Injector,
OnDestroy,
} from '@angular/core';
import { delay, takeUntil } from 'rxjs/operators';
import { of, Subject } from 'rxjs';
import {
NgDiagramComponent,
NgDiagramConfig,
NgDiagramModelService,
NgDiagramNodeTemplateMap,
initializeModel,
provideNgDiagram,
} from 'ng-diagram';
import { NodeComponent } from '../diagram-node/diagram-node';
enum NodeTemplateType {
CustomNodeType = 'customNodeType',
}
@component({
selector: 'app-diagram',
standalone: true,
imports: [NgDiagramComponent],
providers: [provideNgDiagram()],
templateUrl: './diagram.html',
styleUrl: './diagram.scss',
})
export class Diagram implements OnDestroy {
private modelService = inject(NgDiagramModelService);
private injector = inject(Injector);
private destroy$ = new Subject();
nodeTemplateMap = new NgDiagramNodeTemplateMap([
[NodeTemplateType.CustomNodeType, NodeComponent],
]);
model = signal(null);
config = {
edgeRouting: {
defaultRouting: 'bezier',
},
zIndex: {
edgesAboveConnectedNodes: true,
},
zoom: {
zoomToFit: {
onInit: true,
},
},
debugMode: true,
} satisfies NgDiagramConfig;
constructor() {
effect(() => {
this.initializeModelFromApi();
});
}
ngOnDestroy(): void {
try {
this.model.set(null);
this.destroy$.next();
this.destroy$.complete();
} catch (error) {
console.warn('Error removing diagram event listeners:', error);
}
}
private initializeModelFromApi() {
// Mimic API call with 2 second delay
of(this.onAddNodesAndEdges())
.pipe(delay(2000), takeUntil(this.destroy$))
.subscribe((data) => {
this.model.set(initializeModel(data, this.injector));
});
}
onAddNodesAndEdges() {
const nodes = [
{ id: '1', position: { x: 200, y: 250 }, data: { label: 'Node 1' } },
{ id: '2', position: { x: 300, y: 350 }, data: { label: 'Node 2' } },
{ id: '3', position: { x: 600, y: 450 }, data: { label: 'Node 3' } },
];
const edges = [
{
id: '1',
source: '1',
sourcePort: 'port-right',
targetPort: 'port-left',
target: '2',
data: {},
},
{
id: '2',
source: '2',
sourcePort: 'port-right',
targetPort: 'port-left',
target: '3',
data: {},
},
];
return {
nodes,
edges,
};
}
}
`
screenshots:
