简体   繁体   English

knockout和Select2获取所选对象

[英]knockout and Select2 get selected object

I'm working on a project where im using .net web api, knockout and in this example, the jquery plugin select2 . 我正在开发一个项目,我使用.net web api,knockout,在这个例子中,jquery插件select2

What im trying to do is to set some field values after the change of the selection. 我想要做的是在选择更改后设置一些字段值。 The select2 control list is loaded after ajax call and the objects contain more data than just id and text. 在ajax调用之后加载select2控件列表,并且对象包含的数据不仅仅是id和text。 How can i get the rest of the data, so i can fill the other inputs with it? 我如何获得剩余的数据,所以我可以用它来填充其他输入? Shortly, im trying to update a viewmodel after the change of the selection (but i get the data when this plugin makes the ajax call). 很快,我试图在更改选择后更新视图模型(但是当这个插件进行ajax调用时我得到了数据)。

Here is a sample data that the selected object should contain: 以下是所选对象应包含的示例数据:

{
   "Customer":{
      "ID":13,
      "No":"0000012",
      "Name":"SomeName",
      "Address":"SomeAddress",
      "ZipCode":"324231",
      "City":"SimCity",
      "Region":"SS",
      "Phone":"458447478",
      "CustomerLocations":[]
   }
}

Here is where i am for now: 这是我现在的位置:

Sample html: 示例html:

<input type="hidden" data-bind="select2: { optionsText: 'Name', optionsValue: 'ID', sourceUrl: apiUrls.customer, model: $root.customer() }, value: CustomerID" id="CustomerName" name="CustomerName" />
<input type="text" data-bind="........" />
<input type="text" data-bind="........" /> 
etc...

and this is the custom binding: 这是自定义绑定:

ko.bindingHandlers.select2 = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var obj = valueAccessor(),
            allBindings = allBindingsAccessor();

        var optionsText = ko.utils.unwrapObservable(obj.optionsText);
        var optionsValue = ko.utils.unwrapObservable(obj.optionsValue);
        var sourceUrl = ko.utils.unwrapObservable(obj.sourceUrl);
        var selectedID = ko.utils.unwrapObservable(allBindings.value);
        var model = ko.utils.unwrapObservable(obj.model);//the object that i need to get/set

        $(element).select2({
            placeholder: "Choose...",
            minimumInputLength: 3,
            initSelection: function (element, callback) {
                if (model && selectedID !== "") {
                    callback({ id: model[optionsValue](), text: model[optionsText]() });
                }
            },
            ajax: {
                quietMillis: 500,
                url: sourceUrl,
                dataType: 'json',
                data: function (search, page) {
                    return {
                        page: page,
                        search: search
                    };
                },
                results: function (data) {
                    var result = [];
                    $.each( data.list, function( key, value ) {
                        result.push({ id: value[optionsValue], text: value[optionsText] });
                    });
                    var more = data.paging.currentPage < data.paging.pageCount;
                    return { results: result, more: more };
                }
            }
        });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).select2('destroy');
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var obj = valueAccessor(),
            allBindings = allBindingsAccessor();

        var model = ko.utils.unwrapObservable(obj.model);//the object that i need to get/set
        var selectedID = ko.utils.unwrapObservable(allBindings.value);

        $(element).select2('val', selectedID);

        $(element).on("change", function (e) {
            //...
        });
    }
};

Getting the selected id or text is not a problem, but how not to loose the rest of the information after the ajax call? 获取所选的id或文本不是问题,但在ajax调用之后如何不丢失其余信息? Where can i set/get this object so i can have all the data that it contains? 我在哪里可以设置/获取此对象,以便我可以获得它包含的所有数据?

Thank you 谢谢

When you build a object literal for your results, added the full object as a "data" property. 为结果构建对象文字时,将完整对象添加为“数据”属性。

result.push({ id: value[optionsValue], text: value[optionsText], data: value });

Then handle the select2-selected event thrown by select2. 然后处理select2抛出的select2选择事件。 The event object this should contain your object literal as the choice property. 事件对象应包含您的对象文字作为choice属性。

$element.on('select2-selected', function(eventData) {
    if ( eventData.choice ) {
        // item selected
        var dataObj = eventData.choice.data;
        var selectedId = eventData.choice.id;
    } else {
        // item cleared

    }
});

For select2 v4, you can use $(elem).select2('data') to get the selected objects. 对于select2 v4,您可以使用$(elem).select2('data')来获取所选对象。

$('selected2-enabled-elements').on('change', function(e) {
    console.log($(this).select2('data'));
});

Example: https://jsfiddle.net/calvin/p1nzrxuy/ 示例: https//jsfiddle.net/calvin/p1nzrxuy/

For select2 versions before v4.0.0 you can do: 对于v4.0.0之前的select2版本,您可以:

.on("select2-selecting", function (e) {
    console.log(e.object);
})

From v4.0.0 on and upwards the following should work: 从v4.0.0开始及以上,以下应该有效:

.on("select2-selecting", function (e) {
    $(this).select2('data')
})

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

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