gpt4 book ai didi

Angular 和动态添加的 CKEditors 中断

转载 作者:行者123 更新时间:2023-12-05 01:26:39 24 4
gpt4 key购买 nike

我在通过 NgFor 动态添加 CKEditors 渲染时遇到问题与 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f3929d94869f9281b3c1ddc3ddc3de929f839b92ddc7c7" rel="noreferrer noopener nofollow">[email protected]</a> .

Live demo is available here.

@Directive({
selector: 'textarea'
})
class CKEditor {
constructor(_elm: ElementRef) {
CKEDITOR.replace(_elm.nativeElement);
}
}

@Component({
selector: 'my-app',
})
@View({
directives: [NgFor, CKEditor],
template: `
<div *ng-for="#item of items">
{{ item }}: <textarea>{{ item }}</textarea>
</div>
<button (click)="addItem()">Add</button>`
})
class AppComponent {
items = ['default_0', 'default_1'];

constructor() {
this.addItem();
}

addItem() {
var id = 'ckeditor_inst_' + this.items.length;
this.items.push(id);
}
}

您可以看到三个 CKEditor 可以正常工作。然后单击底部的“添加”按钮,它会以一种您甚至可以写入的方式破坏容器中的最后一个 CKEditor,如果您按任何工具栏按钮,它会抛出:

Uncaught TypeError: Cannot read property 'getSelection' of undefined .

有趣的是,只有最后一个 CKEditor 坏了,其他两个都可以工作。看起来 Angular2 以某种方式操纵了破坏 CKEditor 的最后一个元素。

我记得使用相同的方式在<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e4f40495b424f5c6e1c001e001e034f425e464f001d1b" rel="noreferrer noopener nofollow">[email protected]</a>中添加新的CKEditors我认为它在那里起作用,但也许我只是没有注意到。版本 <span class="__cf_email__" data-cfemail="06676861736a67744634283628362b676a766e67283231">[email protected]</span> is the same .

最佳答案

您的集成使用 Classic CKEditor,因为 wysiwygarea 插件可以在 <iframe> 中进行编辑(即避免 CSS 与网页冲突)。

这种实现的缺点是,一旦您从 DOM 中分离(并重新附加)这样的 <iframe> (就像每次添加新的 item 时 Angular 所做的那样),其内部 document 就会“损坏”。我所说的损坏是指 document.body 是从头开始加载的,丢失了你的内容、CKEditor 引导代码、JS 引用等,并最终使整个编辑器实例变得无用。

所以问题在于该 View 的渲染方式:

@View({
directives: [NgFor, CKEditor],
template: `
<div *ng-for="#item of items">
{{ item }}: <textarea>{{ item }}</textarea>
</div>
<button (click)="addItem()">Add</button>`
})

我看到了这个问题的三种解决方案:

  • 干净的解决方案:在添加新项目时强制 Angular 不重新渲染整个 items 集合。
  • 棘手的解决方案:使用 Inline CKEditor,它在 <div contenteditable="true" /> div 而不是 <iframe>...<body contenteditable="true" /></iframe> 中工作,并且不受 DOM 中突变的影响。
  • 懒惰且缓慢的解决方案:坚持当前集成,但在添加新项目之前销毁所有 CKEDITOR.instances ( instance.destroy() ),然后重新初始化它们 CKEDITOR.replace()

关于Angular 和动态添加的 CKEditors 中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34039249/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com