2011-12-20 53 views
0

我使用第三方插件來編輯表格。所以我需要爲<td>創建一個自定義綁定,以便插件引起的對文本所做的任何更改都會觸發視圖模型更新。但是自定義綁定不顯示正確的數據,而不是內置的「文本」綁定。我做錯了什麼嗎?Knockout自定義綁定不會正確顯示初始viewModel數據

請參閱:http://jsfiddle.net/VbeBA/5

HTML:

<table id="table1" cellspacing="0" cellpadding="0" border="0"> 
    <tr> 
     <th style="width:150px">Product</th> 
     <th>Price ($)</th> 
     <th>Quantity</th> 
     <th>Amount ($)</th> 
    </tr> 

    <tbody data-bind='template: {name: "orderTemplate", foreach: orders}'></tbody> 
</table> 

<script type="text/html" id="orderTemplate"> 
    <tr> 
     <td data-bind="text: product">${product}</td> 
     <td class="editable number" data-bind="dataCell: price"></td> 
     <td class="editable number"data-bind="dataCell: quantity">${quantity}</td> 
     <td class="number" data-bind="text: amount">${amount}</td> 
    </tr> 
</script> 

CSS:

table 
{ 
    border: solid 1px #e8eef4; 
    border-collapse: collapse; 
} 

table th 
{ 
    padding: 6px 5px; 
    background-color: #e8eef4; 
    border: solid 1px #e8eef4; 
} 

table td 
{ 
    padding:0 3px 0 3px; 
    margin: 0px; 
    height: 20px; 
    border: solid 1px #e8eef4; 
} 

td.number 
{ 
    width: 100px; 
    text-align:right; 
} 

td.editable 
{ 
    background-color:#fff; 
} 

td.editable input 
{ 
    font-family: Verdana, Helvetica, Sans-Serif; 
    text-align: right; 
    width: 100%; 
    height: 100%; 
    border: 0; 
} 

td.editing 
{ 
    border: 2px solid Blue; 
} 

腳本:

$(function() { 
    ko.bindingHandlers.dataCell = { 

     init: function (element, valueAccessor) { 
      ko.utils.registerEventHandler(element, "change", function() { 
       var value = valueAccessor(); 
       value($(element).text()); 
      }); 
     }, 
     update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
      var value = valueAccessor(); 
      $(element).text(value); 
     } 

    }; 

    var order = function (product, price, quantity) { 
     this.product = product; 
     this.price = ko.observable(price); 
     this.quantity = ko.observable(quantity); 
     this.amount = ko.dependentObservable(function() { 
      return this.price() * this.quantity(); 
     }, this); 
    } 

    var ordersModel = function() { 
     this.orders = ko.observableArray([]); 
    } 


    var viewModel = new ordersModel(); 
    viewModel.orders = ko.observableArray([ 
      new order("Gala Apple", 0.79, 150), 
      new order("Naval Orange", 0.29, 500) 
     ]); 

    ko.applyBindings(viewModel); 

    $(".editable").change(); 
}); 

回答

3

在你update功能,您將婉t解開可觀察的事物。 valueAccessor()將會給你自己的觀測值,然後你想打開它(稱之爲函數)來獲得值。

一個安全的方式做到這一點是使用ko.utils.unwrapObservable,因爲它會容忍這兩個觀測和非觀測。

所以,你的更新將是這樣的:

update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     $(element).text(value); 
    } 

此外,在你的小提琴,你已經jQuery.tmpl淘汰賽後上市,所以KO沒有註冊jQuery的模板引擎。

這裏是一個更新的小提琴:http://jsfiddle.net/rniemeyer/VbeBA/8/

更新時間: 最終的解決方案是在http://jsfiddle.net/rniemeyer/qQaUa/

+0

其實我已經嘗試過這一點。但對我來說問題是它會使jQuery可編輯插件無法正常工作。小提琴http://jsfiddle.net/justinc/VbeBA/9/在Firefox上顯示可編輯的作品,但不是初始綁定,而http://jsfiddle.net/justinc/VbeBA/10/顯示可編輯不起作用與unwrapped可觀察。 Knockout和Editable之間可能存在事件時序衝突? – 2011-12-20 23:51:54

+0

問題在於你的模板是基於'$ {variable}'jQuery模板調用(它創建了依賴關係)重新呈現的。這些都是不必要的,因爲你已經在使用綁定。以下是一個示例:http://jsfiddle.net/rniemeyer/VbeBA/11/ – 2011-12-21 16:07:48

+1

增加了一個更新:http://jsfiddle.net/rniemeyer/qQaUa/。當你訪問更新函數中的基礎值時,它會創建對observable的依賴關係,這很好。但是,更新變更處理程序中的observable時,會觸發更新功能並最終導致內容爲空。更改處理程序只需在當前執行上下文完成後運行其更新。 – 2011-12-21 16:48:25

相關問題