2013-05-14 53 views
2

我有一種情況涉及KnockoutJS和jwysiwyg插件(https://github.com/jwysiwyg/jwysiwyg)。我正在使用下面看到的自定義綁定。但是,只要用戶將文本更新到第二行,通過綁定更新內容就會使光標重置到編輯器的開頭。因此,無論何時用戶在更新後暫停輸入1秒鐘以上,他們都不得不點擊回到之前的位置繼續。Knockout自定義綁定重置所見即所得光標

ko.bindingHandlers.wysiwyg = { 
     init: function (element, valueAccessor, allBindingsAccessor) { 
     var options = allBindingsAccessor().wysiwygOptions || {}; 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     var $e = $(element); 
     $.extend(true, { 
      initialContent : value 
     }, options); 

     $e.wysiwyg(options); 

     //handle the field changing 
     function detectFn() { 
      var observable = valueAccessor(); 
      var newvalue = $e.wysiwyg("getContent"); 
      observable(newvalue); 
     } 

     var current = $e.wysiwyg('document'); 
     var timer; 
     current.bind({  
      keyup: function(){ 
       clearTimeout(timer); 
       timer = setTimeout(detectFn, 1000); 
      } 
     }); 

     //handle disposal (if KO removes by the template binding) 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $e.wysiwyg('destroy'); 
     }); 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     $(element).wysiwyg("setContent", value); 
     ko.bindingHandlers.value.update(element, valueAccessor); 
    } 
}; 

(的結合被此使用)

<textarea data-bind="wysiwyg: yourViewModelValue"></textarea> 

我怎樣才能插入符位置,以恢復光標一旦更新完成?或者有什麼其他解決方案來強制光標在更新時不會移動?

編輯:一個jsfiddle來演示這個問題。 http://jsfiddle.net/797ZL/ 注意當你在第二行或以上輸入時會發生什麼,然後暫停一秒,導致光標重置。

回答

4

這裏是你所看到的:

  1. 用戶鍵入一些文字到所見即所得的編輯器
  2. 用戶停止輸入後1秒超時命中,觸發detectFn
  3. detectFn抓住新所見即所得編輯器的值並更新您的可觀察值
  4. 正在更新的可觀察值會觸發自定義綁定器上的更新方法
  5. 自定義綁定器上的更新方法獲取從可觀察的值,並將它的所見即所得的編輯器
  6. WYSIWYG編輯器,將其具有給它一個新值,光標移動到最上面一行

您可以通過在停止的事情解決這個問題在步驟5的中間,並且只在所見即所得編輯器中更新值,如果它不同於可觀察值 - 也就是說,如果觀察值是從所見即所得編輯器之外的某處更新的。

更改您的更新方法如下:

update: function (element, valueAccessor) { 
    var newValue = ko.utils.unwrapObservable(valueAccessor()); 
    var oldValue = $(element).wysiwyg("getContent"); 
    if (newValue !== oldValue) { 
     $(element).wysiwyg("setContent", newValue); 
    } 
    // ko.bindingHandlers.value.update(element, valueAccessor); 
} 

我評論了該方法的最後一行...看來多餘的,我真的不知道爲什麼它的存在。

而且,這幾行代碼似乎沒有被任何做任何事情:

$.extend(true, { 
    initialContent : value 
}, options); 

我認爲你正在試圖做的是添加initialContent屬性選項對象。可以以這種方式來完成:

$.extend(options, {initialContent: value}); 

然而,即使是不需要的,因爲更新方法是在init方法後調用,並從可觀察的值被加載到當時的所見即所得的編輯器。

這裏是更新的代碼小提琴:http://jsfiddle.net/tlarson/797ZL/2/

+0

很清楚,就像一個魅力。 – derickt