Angular, ng-ckeditor, and the editor-destroy-iframe bug

不羁的心 提交于 2019-11-29 15:35:13

I am using Angular 6 and here is what I did.

I programmatically destroy the iFrame using this

Please Note: I did not want any editor present so I destroyed them all. Its import to note, that if a user is navigating away from, and back to a CKEDITOR you have destroyed a new instance will be created. (editor2...3...4...5 etc) I did not care about the instance int so I destroyed them all and let angular create new instances as it needed based on user interaction.

destroyEditor(){
      let editor = window['CKEDITOR'];
      if(editor.instances){
        for(var editorInstance in editor.instances){
         editor.instances[editorInstance].destroy();
        }
       }
      }

This will allow you to destroy the iframe on any exit condition you have. When a user navigates away from the editor, I call this right before I set my value that changes the UI view and completes the navigation away from the editor.

  • It will leave a text area.
  • If you time it correctly the user will not see this.

You will notice at this point you are still getting an error in the console from ckeditor.component.js

  • This is where you are going to have to make a modification to the library files.
  • This is because the if condition in the CKEditorComponent.prototype.ngOnDestroy function is only checking for the instance and not if the instance name exists.
  • The instance appears to always evaluate to true for me even though the instance has been destroyed. (example:editor1,editor2,editor3 etc)
  • The instance name does not exist when ngDestroy occurs... because... you already destroyed it.

Make this change in the following file.

\node_modules\ng2-ckeditor\lib\src\ckeditor.component.js

This will check for the instance name specifically and not attempt a destroy... because.. you already destroyed it.

CKEditorComponent.prototype.ngOnDestroy = function () {
        var _this = this;
        //if (this.instance) {
        if(CKEDITOR.instances[_this.instance.name]) {
            setTimeout(function () {
                _this.instance.removeAllListeners();
                CKEDITOR.instances[_this.instance.name].destroy();
                _this.instance.destroy();
                _this.instance = null;
            });
        }
    };

If modifying JS-files under node_module is not desired, as in my case, call the following function from ngOnDestroy():

public destroyEditor(): void {
  const editor = window['CKEDITOR'];
  if (editor.instances) {
      for (const editorInstance in editor.instances) {
          if (editor.instances.hasOwnProperty(editorInstance) && 
              editor.instances[editorInstance]) {
              editor.instances[editorInstance].destroy();
              editor.instances[editorInstance] = {
                  destroy: () => true,
              };
          }
      }
}

Note, that after destroying, a dummy object is assigned to the collection item to prevent a JS error, when the component is to be destroyed from the native function. The component must implement OnDestroy interface and the destroyEditor() function called like this:

export class RichTextEditorComponent implements OnDestroy {
    public ngOnDestroy(): void {
        this.destroyEditor();
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!