2013-03-08 66 views
0

我有以下代碼,我試圖使用可寫計算observable來驗證用戶輸入,並自動拒絕無效輸入。 這只是一些測試代碼,我試圖阻止用戶從文本中刪除逗號字符。如果用戶刪除了逗號字符,我試圖將編輯器重新綁定到之前的值以覆蓋最近的更改。 這可能使用可寫計算字段嗎? 我遇到的問題是隻有當我加載頁面(手動設置ValidText道具之後)時,可寫的計算綁定纔會觸發。但是,當用戶鍵入編輯器時,我無法啓動它。KnockoutJS:可寫計算可觀察不更新

代碼:

<script type="text/javascript"> 

    var model = null; 

    function EditModel() { 

     this.Count = 2; 

     var self = this; 

     this.ExistingValue = ko.observable(""); 

     this.ValidText = ko.computed({ 
      read: function() { 
       return self.ExistingValue(); 
      }, 
      write: function (text) { 
       if (text.split(',').length === self.Count) { 
        self.ExistingValue(text); 
       } 
      }, 
      owner: self 
     }); 
    } 

    $(document).ready(function() { 

     model = new EditModel(); 

     model.ValidText('@(Model.Text)'); 

     ko.applyBindings(model); 
    }); 

</script> 

<div id="mainContainer"> 
    <div id="editor" contenteditable="true" class="commentEditBox" data-bind="text: ValidText, valueUpdate: 'afterkeydown'" ></div> 
</div> 

結束了自定義綁定的想法去和轉換的代碼如下:

<script type="text/javascript"> 

    var model = null; 

    ko.bindingHandlers.customEditorBinding = { 
     init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 

      $(element).on('keydown', function() { 
       var observable = valueAccessor(); 
       observable($(this).text()); 
      }); 
     }, 
     update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
      var text = ko.utils.unwrapObservable(valueAccessor()); 

      if (text.split(',').length === model.Count) { 
       model.ValidText(text); 
       model.PreviousText = text; 
       $(element).text(text); 
      } 
      else { 
       model.ValidText(model.PreviousText); 
       $(element).text(model.PreviousText); 
      } 
     } 
    }; 

    function EditModel() { 

     var self = this; 

     self.Count = 2; 

     self.ValidText = ko.observable(""); 

     self.PreviousText = null; 
    } 

    $(document).ready(function() { 

     model = new EditModel(); 

     model.ValidText('This is,a test'); 

     ko.applyBindings(model); 
    }); 

</script> 

<div id="mainContainer"> 
    <div id="editor" contenteditable="true" class="commentEditBox" data-bind="customEditorBinding:ValidText" ></div> 
</div> 

回答

1

好吧,混淆使用的自我,這分開,你已經綁定它使用文本到一個div,並且您正在嘗試在值更改時更新它。這個HTML元素沒有任何價值,所以這就是爲什麼它不會觸發。

看看custom binding並將您的寫入邏輯移到它的更新方法中。

ko.bindingHandlers.yourBindingName = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // This will be called when the binding is first applied to an element 
     // Set up any initial state, event handlers, etc. here 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // This will be called once when the binding is first applied to an element, 
     // and again whenever the associated observable changes value. 
     // Update the DOM element based on the supplied values here. 
    } 
}; 
+1

我同意它不一致,但它應該沒關係。我更新了它,以使用它們,但仍然是相同的問題 – TGH 2013-03-08 16:10:23

+0

夠公平的,但我總是首先尋找最簡單的解釋,並且不一致是開始的好地方!無論如何,試試這個答案。 – 2013-03-08 16:17:11

+0

好吧,酷我得到它的工作。感謝 – TGH 2013-03-08 17:14:50

0

在你寫方法,添加此else子句:

else { self.ValidText.notifySubscribers(self.ExistingValue()); } 

這將迫使文本框更新回原來的值。

+0

的想法問題是,我不能讓它着火。嘗試添加其他的,但它從來沒有達到這種條件,因爲它只在有效時纔開始發射 – TGH 2013-03-08 16:09:02