2012-11-16 74 views
1

我想了解一些有點奇怪的行爲,我在使用KnockoutJS的頁面中看到了一些。每次我清除並重新應用綁定時,可觀察數組似乎都會得到重複項。瞭解這個問題的最快方法是看看這個。只需點擊任何編輯按鈕幾次,並觀看這個列表成長!Knockoutjs ObservableArray保持大小加倍

這個演示代碼的心臟是在下面的方法:

var _bindItemDetail = function (jsonData) { 
     //clear existing bindings 
     ko.cleanNode($("#itemdetails").get(0)); 

     // observables in selected item. 
     _viewModel.SelectedItem(ko.mapping.fromJS(jsonData)); 

     // Apply Bindings 
     ko.applyBindings(_viewModel.SelectedItem, $("#itemdetails").get(0)); 
    }; 

的什麼,我試圖達到的實質是在一個創建列表和詳細信息頁面。列表JSON是在初始頁面加載時獲取的,並且只要單擊編輯鏈接,就會獲取詳細的JSON並綁定到「detail」html。

除了解決問題之外,我還試圖瞭解這些問題,並學習了一些關於如何在使用敲除工具時正確清理陳舊資源的經驗教訓。

感謝所有幫助

回答

2

的問題是,在你的_bindItemDetail功能,您重新應用在你修改視圖中的綁定,您已經有了複製的元素。

var _bindItemDetail = function (jsonData) { 
    //clear existing bindings 
    ko.cleanNode($("#itemdetails").get(0)); 

    // observables in selected item. 
    _viewModel.SelectedItem(ko.mapping.fromJS(jsonData)); 

    // Apply Bindings 
    ko.applyBindings(_viewModel.SelectedItem, $("#itemdetails").get(0)); 
}; 

ko.cleanNode()只是刪除由元素綁定,它不會恢復視圖返回到其初始狀態。一般來說,你只能在一組節點上調用ko.applyBindings一次。不止一次地做,只是在問問題。

坦率地說,你不是真的很好地利用淘汰賽。大部分代碼使用jquery來處理所有低級細節。使用淘汰賽的關鍵是不必擔心這些較低級別的細節。

我已經調整了一下你的小提琴,以便更好地利用淘汰賽,而不太重視使用jquery。

在視圖:

  • 使用的click結合來處理你的Edit click事件。
  • 使用with綁定來有條件地顯示編輯器字段。 stopBindings處理程序不是必需的。

在視圖模型:

  • 添加單擊處理editClicked向視圖模型。
  • 刪除了jquery事件綁定。
  • 刪除了綁定項目時的組合結果ko.cleanNode/ko.applyBindings。你不應該這樣做,你只是不需要它,淘汰賽將處理所有爲你。

Updated fiddle

+0

感謝傑夫!這兩個解決了我的問題,並在合適的淘汰賽中使用我。 「與」綁定是一個有趣的。我以前認爲這只是一種便利的綁定,可以改善上下文的範圍。但是,這似乎更重要 - 尤其是在這種情況下。 Muchas gracias。 – James