Angular,ng-ckeditor和editor-destroy-iframe错误 [英] Angular, ng-ckeditor, and the editor-destroy-iframe bug

查看:97
本文介绍了Angular,ng-ckeditor和editor-destroy-iframe错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此帖子针对的是ng2-ckeditor@1.1.13,其中已加载ckeditor@4.8.0.

This posting is regards ng2-ckeditor@1.1.13 loaded with ckeditor@4.8.0.

尽管有几篇关于SO的文章,但我相信这仍是一个开放的问题.请不要将此帖子标记为重复.

Although there are a couple of articles on SO with this question I believe this is still an open question. Please do not mark this posting as a duplicate.

要复制问题:1)使用 ckeditor 指令实例化DOM元素. 2)导航离开视图,以致破坏托管 ckeditor 的Angular组件.您可以在Javascript控制台中找到它:

To replicate problem: 1) instantiate a DOM element with the ckeditor directive. 2) navigate away from the view in such a way that the Angular Component that is hosting the ckeditor is destroyed. You get this in the Javascript console:

ckeditor.js:19 [CKEDITOR] Error code: editor-destroy-iframe.

在github上有一个已关闭的错误,没有明显的或可接受的解决方案,除非我错过了.如果有解决方案,我们应该在这篇文章中记录它,因为它不完整或模糊.

There is a closed bug on github over this with no apparent or acceptable solution, unless I missed it. If there is a solution there we should document it on this post because it is incomplete or obscure.

问题显然是在 ckeditor 本身被销毁之前,Angular框架销毁了 iframe 元素.这将导致诊断消息.

The problem is apparently that Angular framework destroys the iframe element before the ckeditor itself is destroyed. This causes the diagnostic message.

一种建议的解决方案涉及使用名为 divarea 的插件.据我了解,这将 iframe 替换为 div 元素.这是有问题的,原因是托管页面中的CSS元素将与CKEDITOR使用的CSS混合在一起.

One proposed solution involves the use of a plugin called divarea. From what I understand this replaces the iframe with a div element. The reason this is problematic is that the CSS elements from the hosting page will be mixed in with the CSS that CKEDITOR uses.

另一种建议的解决方案涉及以下代码段:

Another proposed solution involves the following snippet of code:

for (name in CKEDITOR.instances) {
    CKEDITOR.instances[name].destroy(true);
}

SO发布提到了这一点并询问该代码可以插入的位置.没有似乎有效的Angular生命周期事件.即使这样做,也不可接受,因为它会破坏所有CKEDITOR实例,并且在我的应用程序中,页面上可能有多个可能幸免于路由器事件.

This SO posting mentions this and asks for where this code can be inserted. There is no Angular lifecycle event that seems to work. Even if it did this would not be an acceptable fix because it destroys all CKEDITOR instances and in my application there might be more than one on the page that might survive a router event.

沿着这些行,我发现通过这些步骤可以在我的Angular组件中找到我的" CKEDITOR实例.在模板中:

Along those lines I discovered that I can find "my" CKEDITOR instance in my Angular Component with these steps. In the template:

  <ckeditor id="content"
            #editor
            [(ngModel)]="editorContent"
            [config]="{}"
            debounce="500"
            name="content"
  ></ckeditor>

除用于建立局部变量的 #editor 指令外,这是标准配置.然后,您可以在组件中构建如下方法:

Which is standard except for the #editor directive which establishes a local variable. Then in the component you can build a method like this:

declare const CKEDITOR: any;

@Component() ....

  @ViewChild('editor') ckeditor: CKEditorComponent;

  destroyEditor() {
     var name = this.ckeditor.instance.name;
     CKEDITOR.instances[name].destroy(true);
  }

问题是:在哪里调用 destroyEditor 函数? (另一个问题是 destroy(true)方法是否适合调用.)

So the question is: where to call the destroyEditor function? (Other question is whether the destroy(true) method is the right one to call.)

ngOnDestroy 调用它不起作用.从路由器捕获事件也不起作用.还有其他建议吗?

Calling it from ngOnDestroy does not work. Catching an event from the router hasn't worked either. Any other suggestions?

推荐答案

如果不需要修改node_module下的JS文件,就像我这样,请从ngOnDestroy()中调用以下函数:

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,
              };
          }
      }
}

请注意,销毁后,当要从本机函数销毁组件时,会将一个伪对象分配给收集项以防止JS错误. 该组件必须实现OnDestroy接口和destroyEditor()函数,如下所示:

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();
    }
}

这篇关于Angular,ng-ckeditor和editor-destroy-iframe错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆