2

NgFor我在通过with渲染的动态添加的 CKEditors 遇到问题angular@2.0.0-alpha.44

现场演示可在此处获得。

@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 的最后一个元素。

我记得使用相同的方式添加新的 CKEditor angular@2.0.0-alpha.35,我认为它在那里工作,但也许我只是没有注意到。版本angular@2.0.0-alpha.47是一样的

4

2 回答 2

4

由于插件,您的集成使用Classicwysiwygarea CKEditor ,它可以在其中进行编辑<iframe>(即避免 CSS 与网页冲突)。

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

所以问题在于这个视图的呈现方式:

@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()
于 2015-12-03T10:49:39.967 回答
2

此问题已在 中修复beta-15,请参阅:

http://plnkr.co/edit/X5whPqDhLS6RjTR2N8hT?p=preview

于 2016-04-19T07:23:56.633 回答