У меня есть ситуация, связанная с KnockoutJS и CKEditor.
По сути, у нас есть часть нашего сайта, выполненная в стиле «одностраничного» приложения. В настоящее время он состоит всего из 2 страниц, но, вероятно, со временем будет расширяться. В настоящее время это просто страница «списков» и страница «управление» для элементы в списке.
Для самой страницы управления требуется редактор форматированного текста. Мы выбрали CKEditor в качестве решения для всей компании.
Поскольку эти 2 страницы представляют собой «одностраничный» стиль, очевидно, что CKEditor не может зарегистрироваться в элементах управления, потому что их нет при загрузке страницы — достаточно простая проблема, которую можно решить. Итак, в качестве примера я прикрепил CKEditor к событию щелчка, которое отлично сработало.Следующая проблема заключалась в том, что тогда настроенные наблюдаемые Knockout не обновлялись, потому что CKEditor фактически не изменяет текстовую область, к которой он прикреплен, а создает все эти элементы div/html, которые вы фактически редактируете.
Немного погуглив, я нашел пример того, как кто-то делал это с TinyMCE — http://jsfiddle.net/rniemeyer/GwkRQ/поэтому я подумал, что могу адаптировать что-то подобное для CKEditor.
В настоящее время я очень близок к тому, чтобы получить работающее решение, я добился его инициализации и обновления правильных наблюдаемых с помощью этой техники (я опубликую код внизу) и даже правильной отправки обратно на сервер — фантастика.
Проблема, с которой я сейчас сталкиваюсь, связана с частью приложения «Одна страница» и повторной инициализацией CKEditor.
По сути, вы можете щелкнуть из списка, чтобы управлять, а затем сохранить (который возвращается на страницу списка), затем, когда вы переходите к другому «управлению», CKEditor инициализируется, но в нем нет никаких значений, я проверил код обновления (ниже), и «значение» определенно имеет правильное значение, но оно не передается в сам CKEditor.
Возможно, это связано с недостаточным пониманием процесса потока/инициализации для CKEditor, непониманием нокаутирующих привязок или, возможно, с фреймворком, настроенным для нашего одностраничного приложения — я не уверен.
Вот код:
//Test one for ckeditor
ko.bindingHandlers.ckeditor = {
init: function (element, valueAccessor, allBindingsAccessor, context) {
var options = allBindingsAccessor().ckeditorOptions || {};
var modelValue = valueAccessor();
$(element).ckeditor();
var editor = $(element).ckeditorGet();
//handle edits made in the editor
editor.on('blur', function (e) {
var self = this;
if (ko.isWriteableObservable(self)) {
self($(e.listenerData).val());
}
}, modelValue, element);
//handle destroying an editor (based on what jQuery plugin does)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
var existingEditor = CKEDITOR.instances[element.name];
existingEditor.destroy(true);
});
},
update: function (element, valueAccessor, allBindingsAccessor, context) {
//handle programmatic updates to the observable
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).html(value);
}
};
Таким образом, в HTML это довольно стандартный нокаут 'data-bind: ckeditor', который применяет для него привязки при инициализации ViewModel.
Я поставил отладчик; в коде, чтобы увидеть поток, похоже, когда я загружаю первый раз, когда он вызывает init, затем обновляет, когда я захожу во второй раз, он нажимает ko.utils.domNodeDisposal для удаления элементов.
Я пытался не уничтожать его, после чего CKEditor жалуется, что что-то с таким именем уже существует.Я пытался не уничтожать его и проверять, существует ли он, и инициализировать, если нет - это работает в первый раз, но во второй раз у нас нет CKEditor.
Я полагаю, что мне не хватает только одной вещи, которая заставит его работать, но я исчерпал все варианты.
Кто-нибудь знает, как интегрировать эти 3 вещи, которые могут мне помочь?
Есть ли здесь специалисты по нокауту, которые могли бы мне помочь?
Будем признательны за любую помощь.
МД