Michael DeRuscio
Michael DeRuscio

Reputation: 53

Event fired by tinymce editor does not update Angular Component right away

I'm trying to build an angular application around a wordpress instance of tinyMce. Inside the editor there are non-content-editable elements that when clicked will open a modal window outside of the tinymce editor.

However, when clicking the element the modal does not open up until the user moves the mouse outside of the iframe located inside of the editor.

I have a service that handles setting up the tinymce editor. The service registers a click event handler that when clicked will emit an event via a subject object.

My modal class subscribes to the subject which will cause the modal to open whenever an element is clicked on.

Editor Handler Service

private clickSubject: Subject<HTMLElement>;
public clickEvent:Observable<HTMLElement>;

private editorSetup(editor: TinyMceEditor) {
    editor.on("DblClick", e => {
        let elm = e.target as HTMLElement;
        this.clickSubject.next(elm);
    });
}

Modal component

private open(elm:HTMLElement){
    this.isOpen = true;
    console.log("Opening");
}
ngOnInit() {
    this.editorHandler.clickEvent.subscribe(elm =>this.open(elm));
}

I created a StackBlitz app to help demonstrate my issue.

Expected: Clicking the element located in the editor will open up a modal without delay.

Actual: When I click the element, the click event on the editor does fire and the "Opening" message does get logged to the console as well. However, the modal does not become visible until the user moves the mouse outside of the iframe located inside of the editor.

Upvotes: 0

Views: 1215

Answers (1)

yurzui
yurzui

Reputation: 214017

The most likely reason in such cases is that your code is executed in root zone but should be executed in Angular zone.

You can fix it by using NgZone.run method:

@Component({
  selector: 'app-tiny-editor',
  templateUrl: './tiny-editor.component.html'
})
export class TinyEditorComponent implements AfterViewInit, OnDestroy {
  ...

  constructor(private zone: NgZone, ...) { }

  ngAfterViewInit() {
    tinymce.init({
      ...
      setup: editor => {
        this.editor = editor;
        editor.on('dblclick', (e) => {
          let elm = e.target;
          console.log("clicked!");

          this.zone.run(() => {   <============================== make sure we're in ng zone
            this.editorHandler.editorSubject.next(elm);
          });

        });
      }
    });
  }
}

Forked Stackblitz

Upvotes: 3

Related Questions