2011-09-21 54 views
0

我創建了一個具有可觀察屬性的ViewModel。我結合這個數組的ul HTML元素,就像這樣:檢索數據綁定對象

<ul id="sortable" 
    data-bind="template: { name: 'parameterTemplate', 
          foreach: parameters }, 
       visible: parameters().length > 0" 
    style="width: 100%"> 
</ul> 

我的模板是這樣的:

<script type="text/html" id="parameterTemplate"> 
    <li class="ui-state-default parameterItem"> 
     <input type="checkbox" data-bind="checked: isRequired" /> 
     Name: 
     <input data-bind="value: name " /> 
     Type: 
     <input data-bind="value: type " /> 
     Size: 
     <input data-bind="value: size " /> 
     <a href="#" data-bind="click: remove">Delete</a> 
    </li> 
</script> 

我使用jQuery的可拖動和排序的資源重新排序列表的元素。這意味着當用戶改變元素的順序時,顯然ko databind不會被改變,因爲jQuery不知道knockout是否存在。

碰巧我希望我的parameters以用戶配置的相同順序保存。所以我的方法是通過jQuery選擇al liHTML元素,得到一個數組(var items = $(".parameterItem");)。對於items中的每個項目,我如何獲得與li HTML元素關聯的數據綁定挖空元素?

可能嗎?

我的視圖模型:

function parameter(parameterName, parameterType, parameterSize, descriptive, defaultValue, isRequired, ownerViewModel) { 
    this.name = ko.observable(parameterName); 
    this.type = ko.observable(parameterType); 
    this.size = ko.observable(parameterSize); 
    this.label = ko.observable(parameterName); 
    this.descriptive = ko.observable(descriptive); 
    this.defaultValue = ko.observable(defaultValue); 
    this.descriptive = ko.observable(descriptive); 
    this.isRequired = ko.observable(isRequired); 
    this.ownerViewModel = ownerViewModel; 
    this.remove = function() { 
     ownerViewModel.parameters.remove(this) 
    }; 
} 

function excelLoaderViewModel() { 
    this.parameters = ko.observableArray([]); 
    this.newParameterName = ko.observable(); 
    this.newParameterType = ko.observable(); 
    this.newParameterSize = ko.observable(); 
    this.newParameterDescriptive = ko.observable(); 
    this.newParameterIsRequired = ko.observable(); 
    this.newParameterDefaultValue = ko.observable(); 

    this.systemName = ko.observable(); 

    this.addParameter = function() { 
     this.parameters.push(
      new parameter(
       this.newParameterName() 
       , this.newParameterType() 
       , this.newParameterSize() 
       , this.newParameterDescriptive() 
       , this.newParameterDefaultValue() 
       , this.newParameterIsRequired() 
       , this)); 
     this.newParameterName(""); 
     this.newParameterType(""); 
     this.newParameterSize(""); 
     this.newParameterIsRequired(false); 
     this.newParameterDefaultValue(""); 
    } 

var myVM = new excelLoaderViewModel(); 
ko.applyBindings(myVM); 

回答

5

最好的辦法是使用自定義綁定到你的元素讓你observableArray同步,因爲他們拖/下降。

這是我前段時間寫過的post

這裏是一個自定義綁定與jQuery的模板作品:

//connect items with observableArrays 
ko.bindingHandlers.sortableList = { 
    init: function(element, valueAccessor) { 
     var list = valueAccessor(); 
     $(element).sortable({ 
      update: function(event, ui) { 
       //retrieve our actual data item 
       var item = ui.item.tmplItem().data; 
       //figure out its new position 
       var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]); 
       //remove the item and add it back in the right spot 
       if (position >= 0) { 
        list.remove(item); 
        list.splice(position, 0, item); 
       } 
      } 
     }); 
    } 
}; 

這裏是它使用一個樣本:http://jsfiddle.net/rniemeyer/vgXNX/

如果您正在使用淘汰賽1.3測試版沒有jQuery的模板中使用它(或用),那麼你可以在1.3新ko.dataFor可用的方法更換tmplItem行:

//connect items with observableArrays 
ko.bindingHandlers.sortableList = { 
    init: function(element, valueAccessor) { 
     var list = valueAccessor(); 
     $(element).sortable({ 
      update: function(event, ui) { 
       //retrieve our actual data item 
       var item = ko.dataFor(ui.item[0]); 
       //figure out its new position 
       var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]); 
       //remove the item and add it back in the right spot 
       if (position >= 0) { 
        list.remove(item); 
        list.splice(position, 0, item); 
       } 
      } 
     }); 
    } 
}; 
+0

真棒!我在腦海中想象這將是可能的,因爲在MVVM模式中,我能夠獲得綁定項目。這個綁定處理程序很好。所以,如果我正確地理解了它,你會爲'ko'添加一個新的「事件」,當它開始處理時,它會得到'ul'元素,這是一個jQuery'sortable'。每當'sortable'觸發'update'事件時,你就會得到'ui.item',這是一個'li'及其綁定項。無論如何,我現在閱讀knockout文檔關注customBindings,以便充分了解代碼。非常感謝! – ClayKaboom

+1

我認爲你是理解。在某些情況下,您會編寫一些代碼來遍歷li元素,查找其相關數據,並嘗試按照正確的順序重新構建數組。自定義綁定爲你做了幾件事: 1-it設置ul是可排序的(不需要自己連線) 2-it掛鉤到由jQuery UI觸發的'update'事件被移動。從那裏它識別列表中li的新位置並相應地移動其相關數據。 –