1

I am using the latest Angular along with the latest MonacoEditor in order to create an application that allows you to edit code directly in the browser. I had it all working great until today when I realized that the @ViewChild element that I am using to grab the DOM element and bind to the MonacoEditor was triggering hundreds of change detection cycles every second when hover/clicking/etc inside of the editor.

I am using this line to get a handle on the DOM element:

@ViewChild('editor') editor;

My view looks like this:

<div class="row">
    <div #editor style="min-height:600px"></div>
</div>

And lastly to bootstrap it in my application:

this._editor = monaco.editor.create(this.editor.nativeElement, {
    language: 'powershell'
});

As soon as the last code below is ran and the monaco editor is attached to the application, all of a sudden the number of digest cycles increases a ton. Simple mousemove events in the editor causes a change detection and I quickly see thousands of detections occur in just a few seconds. As soon as I remove the bottom lines of code the issues all go away.

The primary reason I am forced to fix this is somehow the editor here is messing with another component altogether and causing the change detection to do some weird things that in-turn causes views to re-render over a again and again. This re-rendering causes my *ngFor loops to fail if I ever use a function to get the iterable object.

I have been poking at this issue for hours before I finally realized it was caused by the Monaco Editor. I have played around with the ChangeDetectionRef class, but detaching the change detection doesn't seem to have any affect on the editor.

I'm fairly new to the latest versions of Angular (recently came from 1.x) so maybe I just need a special way of bootstrapping this editor so it doesn't do this. I want to be able to control the detection manually but I haven't seen that work at all so far using ChangeDetectionRef

UPDATE

Forgot to mention that I did try using ChangeDetectionStrategy.OnPush as well to help control the change detection and it seems to have no effect at all on the underlying detection that is occurring.

Matt Hintzke
  • 7,744
  • 16
  • 55
  • 113
  • 1
    did you try setting `changeDetection: ChangeDetectionStrategy.OnPush` in your component declaration? – Our_Benefactors Feb 05 '19 at 01:50
  • Oh yes, sorry forgot to mention that I tried this and it seemed to have no effect on the digests – Matt Hintzke Feb 05 '19 at 01:53
  • You could try the solution in this answer, using a `@RunOutsideAngular` decorator to completely disable all change detection. It sounds like the monaco editor is emitting tons of events which will keep firing change detection even when you're using onPush. https://stackoverflow.com/questions/44406700/angular-disable-change-detector-for-an-entire-class-service-or-component – Our_Benefactors Feb 05 '19 at 02:05
  • Hmm so I tried that out real quick and it seems to have other side-effects like no longer providing DI for the class so my ActivatedRoute and other injected objects are all `undefined` now. I think this does a little too much. If anything it would be nice to be able to control the change detection at a per-property level – Matt Hintzke Feb 05 '19 at 02:19

1 Answers1

2

This might be somewhat of a radical change, but you might try https://github.com/atularen/ngx-monaco-editor which is an Angular wrapper for the Monaco Editor, rather than trying to integrate it yourself.

GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67
  • This actually did end up fixing the issue at hand after some playing around with my angular.json file to get it to work with 7.x. Thanks a lot! – Matt Hintzke Feb 05 '19 at 21:31