2015-12-02 6 views
2

У меня проблема с динамически добавленными CKEditors, сгенерированными с помощью NgFor с [email protected].Angular2 и динамически добавлены CKEditors break

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

Вы можете увидеть три CKEditors, которые работают правильно. Затем нажмите кнопку «Добавить» внизу, и он разбивает последний CKEditor в контейнере таким образом, что вы можете даже писать на него, и если вы нажмете любую кнопку на панели инструментов, это будет выбрано:

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

Интересно, что только последний CKEditor сломан, остальные два работают. Кажется, что Angular2 каким-то образом манипулирует последним элементом, который разбивает CKEditor.

Я помню, используя тот же способ добавления новых CKEditors в [email protected], и я думаю, что он работал там, но, возможно, я просто не заметил. Версия [email protected] is the same.

ответ

4

В вашей интеграции используется Classic CKEditor из-за плагина wysiwygarea, который позволяет редактировать в (т. Е. Избегать столкновения CSS с веб-страницей).

Недостаток такой реализации является то, что как только вы отсоединять (и повторно присоединять) такой из DOM (например, Угловые делают каждый раз, когда вы добавляете новый 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>` 
}) 

И я вижу три решения этой проблемы:

  • Чистое решение: Force Угловая не пересборку вся коллекция items при добавлении нового элемента.
  • Трудное совпадение: используйте Inline CKEditor, который работает в <div contenteditable="true" /> div вместо <iframe>...<body contenteditable="true" /></iframe> и невосприимчив к мутациям в DOM.
  • Lazy and slow solution: Придерживайтесь текущей интеграции, но уничтожайте все CKEDITOR.instances (instance.destroy()) перед добавлением нового элемента, а затем повторно инициализируйте их CKEDITOR.replace().

 Смежные вопросы

  • Нет связанных вопросов^_^