2016-05-10 1 views
0

CKEditorインライン編集を使用するこのコードはあります。CKEditor +メテオ保存とフラッシングの際に重複するテキスト

#wikiedit(contenteditable="true") 
     !{wikipage.text} 

エディタ領域を編集して閉じた後、サーバーのコマンドが実行されています。問題は、データベースが更新され、クライアントにフラッシュされた後にWikiテキストが複製されていることです。それが更新さだとき、私は、そこに入力するものは何でも

var e = CKEDITOR.instances.wikiedit, 
    save_timeout, 
    save_data = function() { 
     clearTimeout(save_timeout); 
     Meteor.call('wiki.update', {_id: wiki_id, text: e.getSnapshot()}) 
     }; 

e.on('blur', function() { 
    console.log('change event'); 

    clearTimeout(save_timeout); 
    save_timeout = setTimeout(save_data, 2000); 
}); 

は、データベース内のテキストが<p>new text</p>で、CKEditorバージョン要素で、古いテキストが削除されません。後に新しいテキストが追加されます。

助けのヘルパーの種類のコードを置くが、innerHTMLは既に古い+フラッシュされたテキストがあります。しかし、テキストを変更したのが現在のユーザーの場合にのみ機能します。それ以外の場合はテキストが異なり、2番目のコピーがどこから始まるのか分かりません。

答えて

0

これをエディタの状態を確認するヘルパーで解決しました。

Template.document.helpers({ 
    ck_deduplicate: function() { 
     var elt = document.getElementById('wikiedit'); 
     if (elt) { 
      elt.innerHTML = ''; 
     } 
     return this.wikipage.text; 
    } 
}); 

ページのマークアップ:

#wikiedit(contenteditable="true") 
     {{{ ck_deduplicate }}} 

ライブの保存、私は開かれたエディタの内容を保存して更新するように設定いくつかのよりスマートなコードで

を入力します。ライブセービングの最終解決策はthis questionです。

メテオの場合、以下の設定があります。まず、CKEditorの設定。文書を保存する前に、ブックマークを作成しDOMを操作してその要素を保存するようにしました(設定変更あり)。

Template.single_doc.rendered = function() { 
    console.log('rendered') 
    var wiki_id = Router.current().data().wikipage._id, 
     // the method that does the main job of setting up CKEditor 
     assign_change = function(ev) { 
      var e = ev.editor, 

       // timeout is stored to cancel if key is pressed within 2 seconds 
       save_timeout, 

       // data saving function 
       save_data = function() { 
        clearTimeout(save_timeout); 
        var bm = e.getSelection().createBookmarks()[0]; 
        $(bm.startNode).attr('data-selection-bookmark','1'); 

        console.log('update', {_id: wiki_id, text: e.getSnapshot()}); 
        Meteor.call('doc.update', {_id: wiki_id, text: e.getSnapshot()}) 
        }; 

      // config updated to allow spans with our attribute 
      e.on('configLoaded', function() { 
       e.config.extraAllowedContent = "span[data-selection-bookmark]"; 
      }); 

      // watch document changed 
      e.on('change', function() { 
       console.log('change event'); 
       clearTimeout(save_timeout); 
       save_timeout = setTimeout(save_data, 2000); 
      }); 
     }, 

     // unfortunately, had to wrap `editor.on('change')` in the assign_change above 
     // because when `.rendered` is triggered, CKEditor is not loaded yet. 
     // Have to wait for it. 
     assign_event = function() { 
      if (typeof(CKEDITOR) == 'undefined') { 
       setTimeout(assign_event, 100); 
       return; 
      } 

      CKEDITOR.on('instanceReady', assign_change); 
     }; 


    assign_event(); 

} 

次に、手動でCKEditorデータを更新し、必要に応じてカーソルを移動するヘルパーです。

Template.single_doc.helpers({ 
    ck_deduplicate: function() { 
     // the helper either outputs the text into the document on document init 
     // or when the template is re-rendered, it updates CKEditor 
     var elt = document.getElementById('wikiedit'); 

     // if dom works, then it's an update, should work with CKEDITOR 
     if (elt) { 

      // get its instance and create a range object (selection tool in CKE) 
      var e = CKEDITOR.instances.wikiedit, 
       range = e.createRange(); 

      // load the data 
      e.loadSnapshot(this.wikipage.text); 

      // inside the text there is <span> with a bookmark 
      var sel = e.getSelection(), 
       // find the bookmark 
       $span = $(e.document.$).find('[data-selection-bookmark]'); 

      // select before it 
      range.setStartBefore(new CKEDITOR.dom.node($span[0])); 
      // collapse to the start 
      range.collapse(true); 
      // do selection 
      range.select(); 
      // remove the bookmark data 
      $(e.document.$).find('[data-selection-bookmark]').remove(); 
      return ''; 
     } 

     return this.wikipage.text; 
    } 
}); 

1つの欠点は、これを同時に編集する2人では機能しないことです。彼らはいつもカーソルを盗みます。そのためには、メモリに格納された相対位置がうまくいくはずです。しかし、これは一時的な回避策と出発点としては十分です。これが他の人に役立つことを望みます。

関連する問題