简体   繁体   English

检索数据绑定对象

[英]Retrieving data bound object

I created a ViewModel which has an observable property. 我创建了一个具有可观察属性的ViewModel。 I bind this array to an ul HTML element, like this: 我将此数组绑定到ul HTML元素,如下所示:

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

My template is this: 我的模板是这样的:

<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>

I'm using the draggable and sortable resources of jQuery to reorder the elements of the list. 我正在使用jQuery的可拖动和可排序资源来对列表的元素进行重新排序。 This means that when the users changes the order of the element, obviously ko databind is not altered, for jQuery does not know knockout exists. 这意味着当用户更改元素的顺序时,显然ko databind不会更改,因为jQuery不知道敲除的存在。

It so happens that I want my parameters to be saved in the same order the user configured. 碰巧我希望我的parameters以用户配置的相同顺序保存。 So my approach was to select al the li HTML elements via jQuery, getting an array ( var items = $(".parameterItem"); ) . 所以我的方法是通过jQuery选择所有li HTML元素,得到一个数组( var items = $(".parameterItem"); )。 How can I get , for each item in items , the databound knockout element, associated with the li HTML element? 我怎样才能获得,对于每个项目items ,数据绑定淘汰赛元素,与相关的li HTML元素?

Is it possible? 可能吗?

My View Model: 我的视图模型:

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

Your best bet is to use a custom binding to keep your observableArray in sync with your elements as they are dragged/dropped. 最好的选择是使用自定义绑定,以使observableArray与元素在拖放时保持同步。

Here is a post that I wrote about it a while ago. 这是我前一段时间写的一篇帖子

Here is a custom binding that works with jQuery Templates: 这是与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);
                }
            }
        });
    }
};

Here is a sample of it in use: http://jsfiddle.net/rniemeyer/vgXNX/ 这是一个正在使用的示例: http : //jsfiddle.net/rniemeyer/vgXNX/

If you are using it with Knockout 1.3 beta without jQuery Templates (or with), then you can replace the tmplItem line with the new ko.dataFor method available in 1.3: 如果您将其与不带jQuery模板(或带有jQuery模板)的Knockout 1.3 beta一起使用,则可以将tmplItem行替换为1.3中可用的新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);
                }
            }
        });
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM