I am struggling with an instance of an ngx-monaco-editor
inside a primeng tab panel which seems to loses its size calculations when switching to another tab, changing the model value bound to the editor and then switching back to the initial tab again.
https://stackblitz.com/edit/primeng9-tabs-monaco-editor
Steps to replicate using URL above:
Before:
After:
Inspecting in the Dom, the originally assigned style is still present.
As you can see from the source code in my sample app, I also tried using the editor's layout
method in the tab change event to attempt to force a recalculation of the size based on the container but this has made no difference
Interestingly if I resize the window this does seem to trigger the editor component to resize again correctly.
Not sure what the root cause is but using *ngIf
on the editor container fixes the problem. Please take a look at this -
handleTabChange(tabChangeEvent: { originalEvent: Event; index: number }) {
if (tabChangeEvent.index === 0) {
//this.monacoEditor.editor.layout();
this.showEditor = true;
} else {
this.showEditor = false;
}
}
Then in your template -
<div style="height: 500px" *ngIf="showEditor">
<ngx-monaco-editor #monacoEditor style="height:100%;" [options]="editorOptions" [(ngModel)]="code">
</ngx-monaco-editor>
</div>
First of all, note that the issue is not related to angular component. This is all about Monaco editor.
Consider a page with a visible Monaco editor inside a container. When Monaco editor is loaded, it sets the layout size according to visible view. So what happens if you request an update on Monaco when is inside a hidden container? Obviously, there's no visible view for Monaco to set its layout props. The editor sets layout according to hidden view! This is why you see a dot instead of area. Now when this view comes to visible state, the editor doesn't update the layout even by calling .layout()
method or setting automaticLayout: true
in options
. You may trigger by resizing the browser, updating editor again or some Angular tricks.
Now you understand how it works. So please avoid updating Monaco when is inside an invisible view. Let this to be done after containing view become visible.
Using *ngIf
will initialize / destroy the ngx-monaco-editor
component, which may or may not be helpful.
When I have a component containing a ngx-monaco-editor
, I create the following function that I call whenever I need to resize the monaco editor.
resizeComponents() {
setTimeout(() => {
window.dispatchEvent(new Event('resize'));
}, 200);
}
<div (click)="onTabChange('myTab')">Change Tab</div>
onTabChange(myTab) {
// execute tab change logic
this.resizeComponents()
}
Again, this is an alternative approach in case you don't want to re-initialize the editor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With