检索数据绑定对象

时间:2011-09-21 16:21:24

标签: c# jquery knockout.js

我创建了一个具有可观察属性的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不知道敲除存在。

碰巧我希望我的parameters按照用户配置的顺序保存。所以我的方法是通过jQuery选择li HTML元素,得到一个数组(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);

1 个答案:

答案 0 :(得分: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/

如果您在没有jQuery模板(或使用)的情况下使用Knockout 1.3 beta,那么您可以使用1.3中提供的新tmplItem方法替换ko.dataFor行:

//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);
                }
            }
        });
    }
};