2013-10-23 30 views
3

在KO 3.0.0.beta(和我幾乎可以肯定這會是相同的2.3)我想新行添加到動態創建的表:焦點輸入動態添加到observableArray在淘汰賽

HTML

<div id="root"> 
    <table> 
     <tbody data-bind="foreach: events"> 
      <tr> 
       <td> 
        <input type="text" data-type="name" data-bind="value: name, css: {hidden: !editing()}, hasFocus: true"> 
       </td> 
       <td> 
        <input type="text" data-type="method" data-bind="value: age, css: {hidden: !editing()}"> 
       </td> 
      </tr> 
     </tbody> 
    </table> 
</div> 

的JavaScript

var $root = $('#root'); 

$root.on('blur', 'table input', function(event) { 
    var data = ko.dataFor(event.target), 
     context = ko.contextFor(event.target), 
     $input = $(event.target), 
     newData; 

    data.editing(false); 

    if($input.closest('td').is(':last-child') && $input.closest('tr').is(':last-child')) { 
     newData = { 
      name: '', 
      age: '', 
      editing: ko.observable(false) 
     }; 

     context.$root.events.push(newData); 
     newData.editing(true); 
    } 
}); 

var data = {     
    events: [ 
     {name: 'aaa', age: '22', editing: false}, 
     {name: 'bbb', age: '33', editing: false}, 
     {name: 'ccc', age: '44', editing: false} 
    ] 
}; 

var mapping = { 
    events: { 
     key: function(data) { 
      return ko.unwrap(data.name); 
     } 
    } 
}; 

var observable = ko.mapping.fromJS(data, mapping); 

ko.applyBindings(observable, $root[0]); 

JSFiddle

and it 差不多的作品。

我成功地創建了行 - 這是siple部分,但對於我的生活,我無法使創建的raw中的第一個輸入被聚焦。

任何想法(和我經歷了很多建議,其中沒有任何工作在上述設置)?

+2

你在混合jQuery和KO,它註定要失敗。添加可觀察的isFocused,將其與hasFocus綁定綁定 – Anders

+1

Second @Anders。你應該把它變成一個答案。這可能不是OP的結果,但它是解決實際問題的最簡單方法,此外:其他人也可能會發現它有幫助。 – Jeroen

+0

@Anders jquery用於事件綁定。完全正交。我接受建議,所以請做出這個答案。我試着用isFocused。無法讓它工作。 – ZenMaster

回答

0

我可能會錯過這一點,但爲什麼不直接將hasFocus設置爲editing()而不是true?

<div id="root"> 
    <table> 
     <tbody data-bind="foreach: events"> 
      <tr> 
       <td> 
        <input type="text" data-type="name" data-bind="value: name, css: {hidden: !editing()}, hasFocus: editing()"> 
       </td> 
       <td> 
        <input type="text" data-type="method" data-bind="value: age, css: {hidden: !editing()}"> 
       </td> 
      </tr> 
     </tbody> 
    </table> 
</div> 

小提琴here

+0

你嘗試過自己的小提琴嗎?它不起作用。感謝您的回覆。 – ZenMaster

+0

我一定是誤解......那麼它應該如何運作呢? –

+0

添加的新行應具有焦點的第一個輸入字段 - 以便用戶可以在按上一行之前的「標籤」之後立即鍵入。 – ZenMaster

0

經常支付的,以避免與淘汰賽這樣的混合jQuery的。對於大多數情況,Knockout也有選項。在你的情況下,要看的是the event bindingthe hasFocus binding

看你的代碼,我會更新這樣的查看到的東西:

<tr> 
    <td> 
     <input type="text" data-bind="value: name, 
             hasFocus: editingName"> 
    </td> 
    <td> 
     <input type="text" data-bind="value: age, 
             hasFocus: editingAge, 
             event: { blur: $root.onBlurAgeEdit }"> 
    </td> 
</tr> 

順便說一句,如果你是後的新行「的MS Word風格」的創作,當用戶按下標籤,你也可以綁定到「按鍵」事件並檢查正確的鍵碼(對於標籤)。

請注意,我已經在兩個觀察值中分割了editing可觀察值:editingNameeditingAge

功能onBlurAgeEdit會在年齡input變模糊時觸發。它看起來像這樣:

self.onBlurAgeEdit = function (item) { 
    // Unwrap the array 
    var myEvents = self.events(); 

    // Check if this function was called for the *last* item in the array 
    if (myEvents[myEvents.length-1] === item) { 

     // Make sure the last item isn't in edit mode anymore 
     item.editingAge(false); 

     // Push a new item that has *name* in edit mode 
     self.events.push({name: ko.observable(''), 
          age: ko.observable(''), 
          editingName: ko.observable(true), 
          editingAge: ko.observable(false)}); 
    } 
}; 

注意,對於Firefox you'll need to throttle的觀測,使hasFocus結合發揮好。

this fiddle的工作中查看這一切。

+0

我必須解釋它真的很糟糕。你的**完全**我的原始作品。這並不好。在最後一個可見輸入上按下tab鍵之後 - 應該添加一個新行,並且該行中的第一個輸入應該被**聚焦**並準備鍵入。另外,你可以看到我在上面的代碼中使用了'hasFocus'。 – ZenMaster

+0

正確的行爲*確實發生在IE10中。令我驚訝的是Webkit沒有工作[直到我讓onBlur函數的一部分運行在它自己的線程上](http://jsfiddle.net/hDCa4/2/)。雖然我沒有時間讓它在Firefox上工作,但直線上的油門延伸看起來沒有效果。有關更多信息,您可能需要按照提及的鏈接進行調查。 – Jeroen