knockout和Select2获取所选对象

时间:2014-02-17 23:00:53

标签: javascript jquery knockout.js asp.net-web-api jquery-select2

我正在开发一个项目,我使用.net web api,knockout和本例中的jquery插件select2

我想要做的是在更改选择后设置一些字段值。 在ajax调用之后加载select2控件列表,并且对象包含的数据不仅仅是id和text。 我如何获得剩余的数据,所以我可以用它来填充其他输入? 很快,我试图在选择更改后更新一个viewmodel(但是当这个插件进行ajax调用时我得到了数据)。

以下是所选对象应包含的示例数据:

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

这就是我现在所处的位置:

示例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...

这是自定义绑定:

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

获取所选的id或文本不是问题,但是在ajax调用之后如何不丢失其余的信息? 我在哪里可以设置/获取此对象,以便我可以获得它包含的所有数据?

谢谢

3 个答案:

答案 0 :(得分:7)

为结果构建对象文字时,将完整对象添加为“数据”属性。

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

然后处理select2抛出的select2选择事件。事件对象应包含您的对象文字作为选择属性。

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

    }
});

答案 1 :(得分:4)

对于select2 v4,您可以使用$(elem).select2('data')来获取所选对象。

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

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

答案 2 :(得分:0)

对于v4.0.0之前的select2版本,您可以执行以下操作:

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

从v4.0.0及以上开始,以下内容应该有效:

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