Asp.net-Mvc

淘汰賽、CKEditor 和單頁應用程序

  • May 26, 2015

我遇到了涉及 KnockoutJS 和 CKEditor 的情況。

基本上,我們網站的一部分是“單頁”應用程序樣式,目前它只涉及 2 個頁面,但可能會隨著時間的推移而擴展,目前它只是一個“列表”頁面和一個用於項目的“管理”頁面列表。

管理頁面本身需要某種富文本編輯器,我們已經使用 CKEditor 為公司範圍的解決方案。

因為這 2 個頁面是“單頁”樣式,顯然 CKEditor 無法註冊管理元素,因為它們在頁面載入時不存在 - 很簡單的問題可以解決。因此,作為一個範例,我將 CKEditor 附加到了一個效果很好的點擊事件上。下一個問題是,已經設置的 Knockout observables 沒有得到更新,因為 CKEditor 實際上並沒有修改它附加的文本區域,它創建了所有這些你實際編輯的 div/html 元素。

經過一番Google搜尋後,我找到了一個使用 TinyMCE 執行此操作的範例 - <http://jsfiddle.net/rniemeyer/GwkRQ/>所以我想我可以為 CKEditor 調整類似的內容。

目前我已經非常接近有一個可行的解決方案了,我已經使用這種技術初始化和更新了正確的 observables(我將在底部發布程式碼),甚至正確地發回伺服器 - 太棒了。

我目前遇到的問題是“單頁”應用程序部分和 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 中,它是一個相當標準的淘汰賽“數據綁定:ckeditor”,它在 ViewModel 初始化時為其應用綁定。

我放了調試器;在程式碼中查看流程,看起來當我第一次載入時它呼叫 init,然後更新,當我第二次進入時它會點擊 ko.utils.domNodeDisposal 來處理元素。

我試過不破壞它,然後 CKEditor 抱怨該名稱已經存在。我試過不破壞它並檢查它是否存在並初始化如果它不存在 - 第一次有效,但第二次我們沒有 CKEditor。

我認為我缺少的只有一件事可以讓它發揮作用,但我已經用盡了所有選擇。

有誰知道整合這三件事可以幫助我嗎?

有沒有可以幫助我的淘汰專家?

任何幫助將非常感激。

醫學博士

對於任何感興趣的人,我對其進行了排序:

這只是一個基本的執行順序,我只需要在初始化之前將值設置為 textarea html。

請注意,這使用 jquery 適配器擴展來對元素執行 .ckeditor() 。

可能還有更好的方法來完成“模糊”部分。

此擴展目前也不適用於選項,但相比之下應該非常簡單。

ko.bindingHandlers.ckeditor = {
   init: function (element, valueAccessor, allBindingsAccessor, context) {
       var options = allBindingsAccessor().ckeditorOptions || {};
       var modelValue = valueAccessor();
       var value = ko.utils.unwrapObservable(valueAccessor());

       $(element).html(value);
       $(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);
   }
};

引用自:https://stackoverflow.com/questions/10713155