2013-04-29 26 views
6

所以我試圖從CKEditor集成內聯編輯與Knockout.js。我能夠成功加載CKEditor和knockout.js。嵌入式CKEditor與knockoutjs集成

我似乎無法得到ko.observable更新的屬性:

<script type="text/javascript"> 

    var viewModel = function() { 
     var self = this; 
     self.editorText = ko.observable('ABC'); 
     self.testNewValue = function() { 
      console.log(this.editorText()); 
     }; 
    } 

    ko.applyBindings(new viewModel()); 
</script> 

下面是HTML:

<div id="editable" contenteditable="true" data-bind="html: editorText"> 
</div> 
<div> 
    <input type="button" data-bind="click: testNewValue" value="test" /> 
</div> 

的結果的console.log總是顯示 「ABC」 不管如果你更新或沒有。注意:我也嘗試過data-bind="text: editorText"

+1

html綁定是[不是雙向](https://github.com/SteveSanderson/knockout/issues/430)。你需要創建自己的[contenteditable自定義綁定](http://stackoverflow.com/questions/7904522/knockout-content-editable-custom-binding)。 – nemesv 2013-04-29 17:26:56

+0

就是這樣。謝謝! – jmogera 2013-04-29 17:33:22

+0

還有Froala,它不會把你的CSS內聯。淘汰賽插件:https:// github。com/froala/knockout-froala – 2015-11-03 17:24:18

回答

11

您必須編寫自定義綁定處理程序,以便將您的observable屬性與CKEditor的實例鏈接。

首先,您可以從找到的自定義綁定開始here。其中一個帖子包含自定義綁定,但我不確定它是否有效。你必須檢查。我把它抄了下來這裏,學分不要去我當然是:

ko.bindingHandlers.ckEditor = { 

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var txtBoxID = $(element).attr("id"); 
     var options = allBindingsAccessor().richTextOptions || {}; 
     options.toolbar_Full = [ 
      ['Source', '-', 'Format', 'Font', 'FontSize', 'TextColor', 'BGColor', '-', 'Bold', 'Italic', 'Underline', 'SpellChecker'], 
      ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl'], 
      ['Link', 'Unlink', 'Image', 'Table'] 
     ]; 

     // handle disposal (if KO removes by the template binding) 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      if (CKEDITOR.instances[txtBoxID]){ 
       CKEDITOR.remove(CKEDITOR.instances[txtBoxID]); 
      } 
     }); 

     $(element).ckeditor(options); 

     // wire up the blur event to ensure our observable is properly updated 
     CKEDITOR.instances[txtBoxID].focusManager.blur = function() { 
      var observable = valueAccessor(); 
      observable($(element).val()); 
     }; 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var val = ko.utils.unwrapObservable(valueAccessor()); 
     $(element).val(val); 
    } 
} 

一個典型的應用則是在HTML:

<textarea id="txt_viewModelVariableName" 
      data-bind="ckEditor: viewModelVariableName"></textarea> 

其次,你可以檢查出custom binding handler for TinyMCE最初寫的瑞恩尼邁耶和其他有才華的人更新。也許TinyMCE可以爲你而不是CKEditor?

+0

它適用於內聯編輯嗎? – jmogera 2013-04-29 17:40:14

+0

犯錯,我真的不知道。我首先需要去CKEditor4的網站了解「內聯編輯」的意思:-)但看到它的最好方法是編寫代碼:-) – Jalayn 2013-04-29 17:42:49

+3

Steve Sanderson是knockoutJs的創建者,Ryan Niemeyer只是一個很棒的的傢伙。 – 2013-07-22 13:46:45

2

要回答您的具體問題,您需要跟蹤編輯的來源,以便更新不會觸發兩次。當observable不是從編輯器更新時,您不希望編輯器中的突然更改重新更新observable。當編輯器更新observable時,同樣的想法,你不希望observable再次通知編輯器。我習慣布爾人跟蹤他們。編輯不可知的代碼如下:

var isObservableChange = false; 
var isEditorChange = false; 

editor.change = function() { 
    if(!isObservableChange){ 
     isEditorChange = true; 
     observable(editor.data); 
     isEditorChange = false; 
    } 
}; 

observable.subscribe(function (newValue) { 
    if(!isEditorChange){ 
     isObservableChange = true; 
     editor.data = observable(); 
     isObservableChange = false; 
    } 
}); 

我有一個項目,我試圖用CKEditor進行內聯編輯。我終於放棄了,並嘗試使用相同類型的代碼TinyMCE,並且解決方案工作。下面的例子使用knockout 2.3.0,tinymce 4.0.8和jquery 1.10.2。 jquery可以被常規的文檔id訪問替換,但是我使用jquery作爲快速代碼的柺杖。綁定代碼如下:

ko.bindingHandlers.wysiwyg = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var value = valueAccessor(); 
     var valueUnwrapped = ko.unwrap(value); 
     var allBindings = allBindingsAccessor(); 
     var $element = $(element); 
     $element.attr('id', 'wysiwyg_' + Date.now()); 
     if (ko.isObservable(value)) { 
      var isSubscriberChange = false; 
      var isEditorChange = true; 
      $element.html(value()); 
      var isEditorChange = false; 

      tinymce.init({ 
       selector: '#' + $element.attr('id'), 
       inline: true, 
       plugins: [ 
        "advlist autolink lists link image charmap print preview anchor", 
        "searchreplace visualblocks code fullscreen", 
        "insertdatetime media table contextmenu paste" 
       ], 
       toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image", 
       setup: function (editor) { 
        editor.on('change', function() { 
         if (!isSubscriberChange) { 
          isEditorChange = true; 
          value($element.html()); 
          isEditorChange = false; 
         } 
        }); 
       } 
      }); 
      value.subscribe(function (newValue) { 
       if (!isEditorChange) { 
        isSubscriberChange = true; 
        $element.html(newValue); 
        isSubscriberChange = false; 
       } 
      }); 
     } 
    } 
} 

要使用它只是將其綁定到一個div。像這樣

<div data-bind="wysiwyg: test"></div> 

工作示例可以在這裏http://jsfiddle.net/dhQk/2xjKc/ 發現我希望這有助於。

編輯:

它看起來像CKEditor版本畢竟工作。我只需要使用不同的cdn。該鏈接是http://jsfiddle.net/dhQk/CSwr6/