2013-04-29 36 views
6

Vì vậy, tôi đang cố gắng tích hợp Chỉnh sửa nội dòng từ CKEditor với Knockout.js. Tôi có thể tải thành công CKEditor và knockout.js.Tích hợp CKEditor nội tuyến với knockoutjs

Tôi chỉ dường như không thể có được cập nhật ko.observable tài sản:

<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> 

Đây là html:

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

Kết quả console.log luôn luôn hiển thị "ABC" không phân biệt nếu bạn cập nhật nó hay không. Lưu ý: Tôi cũng đã thử data-bind="text: editorText"

+1

Liên kết html là [không hai chiều] (https://github.com/SteveSanderson/knockout/issues/430). Bạn cần tạo [liên kết tùy chỉnh riêng cho nội dung có thể chỉnh sửa] của riêng bạn (http://stackoverflow.com/questions/7904522/knockout-content-editable-custom-binding). – nemesv

+0

Vậy đó. Cảm ơn bạn! – jmogera

+0

Ngoài ra còn có Froala, mà sẽ không đặt css của bạn nội tuyến. Plugin Knockout: https: // github.com/froala/knockout-froala –

Trả lời

11

Bạn phải viết trình xử lý ràng buộc tùy chỉnh để cho thuộc tính quan sát của bạn được liên kết với một phiên bản của CKEditor.

Trước tiên, bạn có thể bắt đầu từ liên kết tùy chỉnh được tìm thấy here. Một trong những bài viết có chứa một ràng buộc tùy chỉnh, mặc dù tôi không chắc chắn nó hoạt động. Bạn phải kiểm tra. Tôi sao chép nó xuống đây, tín dụng không đi với tôi tất nhiên:

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

Một sử dụng điển hình sau đó sẽ là trong HTML:

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

Thứ hai, bạn có thể kiểm tra custom binding handler for TinyMCE ban đầu được viết bởi Ryan Niemeyer và được cập nhật bởi những người tài năng khác. Có lẽ TinyMCE có thể phù hợp với bạn thay vì CKEditor?

+0

có áp dụng cho chỉnh sửa nội dòng không? – jmogera

+0

err, tôi thành thật không biết. Đầu tiên tôi cần đến trang web của CKEditor4 để biết "chỉnh sửa nội tuyến" có nghĩa là :-) Nhưng cách tốt nhất để xem nó là viết mã :-) – Jalayn

+3

Steve Sanderson là tác giả của knockoutJs, Ryan Niemeyer chỉ là một tuyệt vời chàng. –

2

Để trả lời câu hỏi cụ thể của bạn, bạn cần phải theo dõi vị trí của bản chỉnh sửa để bản cập nhật không được kích hoạt hai lần. Khi quan sát được cập nhật không phải từ trình chỉnh sửa, bạn không muốn thay đổi đột ngột trong trình chỉnh sửa để cập nhật lại quan sát được. Cùng một ý tưởng khi biên tập viên cập nhật các quan sát, bạn không muốn các quan sát để thông báo cho các biên tập viên một lần nữa. Tôi đã từng sử dụng boolean để theo dõi chúng. Mã trình chỉnh sửa-thuyết bất khả tri là bên dưới:

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

Tôi đã cố gắng hết sức để chỉnh sửa nội dòng bằng CKEditor. Cuối cùng tôi đã từ bỏ và thử TinyMCE với cùng một loại mã và giải pháp đã hoạt động. Ví dụ sau sử dụng loại bỏ 2.3.0, tinymce 4.0.8 và jquery 1.10.2. Các jquery có thể được thay thế bằng cách truy cập id tài liệu thông thường, nhưng tôi sử dụng jquery như một cái nạng cho mã nhanh. Mã ràng buộc như sau:

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

Để sử dụng nó, hãy liên kết mã đó với div. như vậy

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

Một ví dụ làm việc có thể được tìm thấy ở đây http://jsfiddle.net/dhQk/2xjKc/ Tôi hy vọng điều này sẽ giúp.

CHỈNH SỬA:

Dường như phiên bản CKEditor hoạt động sau tất cả. Tôi chỉ cần sử dụng một cdn khác. Liên kết cho điều đó là http://jsfiddle.net/dhQk/CSwr6/

Các vấn đề liên quan