2011-06-18 48 views
1

我結合一個observableArray到產生與<tr>的表陣列中的每個項的模板。我們的想法是,當用戶進入最後一排文字,頁面會自動添加另一行;這是項動態擴展列表。更新observableArray結合形成表導致失去焦點

這一切工作正常,但是當這種情況發生的鍵盤焦點將丟失。我張貼破裂的試樣in this fiddle,其中包含以下內容:

function ingredientViewModel(name, qty, note) { 
    this.name = ko.observable(name); 
    this.quantity = qty; 
    this.note = note; 
} 

var viewModel = { 
    ingredients: ko.observableArray([]), 
}; 

// When last ingredient's name changes, 
// Add a new row to the list 
// Update the global subscription to point to the new item 


function lastIngredientNameChanged(newValue) { 
    var currentfocus = document.activeElement; 
    if (newValue != '') { 
     lastIngredientSubscription.dispose(); 
     viewModel.ingredients.push(new ingredientViewModel('', '', '')); 
     lastIngredientSubscription = viewModel.ingredients()[viewModel.ingredients().length - 1].name.subscribe(lastIngredientNameChanged); 
    } 
    currentfocus.focus(); 
} 

// Set up initial entries 
viewModel.ingredients.push(new ingredientViewModel('', '', '')); 
var lastIngredientSubscription = viewModel.ingredients()[viewModel.ingredients().length - 1].name.subscribe(lastIngredientNameChanged); 

ko.applyBindings(viewModel); 

這種觀點代碼:

<script type="text/html" id="ingredientTemplate"> 
    < table id = "ingredienttable" > <colgroup> < col width = "200"/> < col width = "40"/> < col/> < /colgroup> 
     <thead><tr> 
      <td>Name</td > <td> Amount < /td> 
      <td>Note</td > < /tr></thead > <tbody> { 
     { 
      each ingredients 
     } 
    } < tr class = "ingrediententry" > <td> < input class = "ingredientautocomplete" 
    data - bind = "value: name, valueUpdate: 'afterkeydown'"/> < /td> 
       <td><input data-bind="value: quantity"/> < /td> 
       <td><input data-bind="value: note"/> < /td> 
      </tr > { 
     { 
      /each}} 
     </tbody > < /table> 
</script> 
<div data-bind="template: 'ingredientTemplate'"></div> 

任何想法?

回答

3

的問題是,當你使用{{每個}}和您的循環變化observableArray,那麼整個模板重新呈現。所以,你的currentfocus元素實際上是走了。

你可以做的是切換到使用模板綁定的foreach選項,該選項只會重新呈現模板中已更改的行。你的HTML看起來像:

<script type="text/html" id="ingredientTemplate"> 
    <table id="ingredienttable"> 
     <colgroup> 
      <col width="200"/> 
      <col width="40"/> 
      <col/> 
     </colgroup> 
     <thead><tr> 
      <td>Name</td> 
      <td>Amount</td> 
      <td>Note</td> 
      </tr></thead> 
     <tbody data-bind="template: { name: 'rowTmpl', foreach: ingredients }"> 
     </tbody> 
    </table> 
</script> 

<script id="rowTmpl" type="text/html"> 
    <tr class="ingrediententry"> 
     <td><input class="ingredientautocomplete" data-bind="value: name, valueUpdate: 'afterkeydown'" /></td> 
     <td><input data-bind="value: quantity" /></td> 
     <td><input data-bind="value: note" /></td> 
    </tr> 
</script> 

<div data-bind="template: 'ingredientTemplate'"></div> 

樣品在這裏:http://jsfiddle.net/rniemeyer/T9UP6/

如果你這樣做,那麼你甚至不用跟蹤currentfocus,它只會保留。