使用Select2仅加载一次远程数据

时间:2013-12-20 10:30:53

标签: javascript jquery-plugins web

正如标题所示,我只想加载一次远程数据。 我想过用一个独立的ajax调用来加载一个数据并在控件上“设置”它,但是想知道是否有更多的“内置”方法可以这样做...

4 个答案:

答案 0 :(得分:7)

可在此处找到解决方案:

https://github.com/ivaynberg/select2/issues/110

$("#selIUT").select2({
    cacheDataSource: [],
    placeholder: "Please enter the name",
    query: function(query) {
        self = this;
        var key = query.term;
        var cachedData = self.cacheDataSource[key];

        if(cachedData) {
            query.callback({results: cachedData.result});
            return;
        } else {
            $.ajax({
              url: '/ajax/suggest/',
              data: { q : query.term },
              dataType: 'json',
              type: 'GET',
              success: function(data) {
                self.cacheDataSource[key] = data;
                query.callback({results: data.result});
              }
            })
        }
    },
    width: '250px',
    formatResult: formatResult, 
    formatSelection: formatSelection, 
    dropdownCssClass: "bigdrop", 
    escapeMarkup: function (m) { return m; } 
}); 

编辑:

我可能误解了你的问题。如果你想加载一次所有数据,那么使用Select2,没有内置的功能来做到这一点。

您建议执行单个查询,然后在Select2中使用该存储的数据将是您的选择。

答案 1 :(得分:0)

一次加载数据:

假设:

  • 您在/ services处有一个REST API端点,用于提供JSON对象数组

  • 数组包含至少具有“name”和“id”属性的对象。例如:

    [{"id": 0, "name": "Foo"}, {"id": 1, "name": "Bar"}]
    
  • 您希望将该数组存储为全局“services_raw”

首先,我们加载数据并创建全局'services_raw'的功能(AKA'window.services_raw'):

  fetchFromAPI = function() {
        console.log("fetchFromAPI called");
        var jqxhr = $.ajax(
            {
                dataType:'json',
                type: 'GET',
                url: "/services",
                success: function(data, textStatus, jqXHR) {
                    services_raw = data;
                    console.log("rosetta.fn.fetchServicesFromAPI SUCCESS");
                    rosetta.fn.refreshServicesSelect();
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    console.log("Error inside rosetta.fn.fetchServicesFromAPI", errorThrown, textStatus, jqXHR);
                    setTimeout(rosetta.fn.fetchServicesFromAPI(), 3000);  // retry in 3 seconds
                }
            }
        )
            .done(function () {
                console.log("success");
                console.log(jqxhr);
            })
            .fail(function () {
                console.log("error");
            })
            .always(function () {
                console.log("complete");
            });

        // Perform other work here ...

        // Set another completion function for the request above
        jqxhr.always(function () {
            console.log("second complete");
        });
    };

其次,我们的Select2实例化代码将我们的数据转换为Select2可以使用的格式:

refreshServicesSelect = function () {
    // ref: http://jsfiddle.net/RVnfn/2/
    // ref2: http://jsfiddle.net/RVnfn/101/    # mine
    // ref3: http://jsfiddle.net/RVnfn/102/    # also mine

    console.log('refreshServicesSelect called');
    $("#add-service-select-service").select2({
        // allowClear: true
        data: function() {
            var arr = [];  // container for the results we're returning to Select2 for display

            for (var idx in services_raw) {
                var item = services_raw[idx];
                arr.push({
                    id: item.id,
                    text: item.name,
                    _raw: item  // for convenience
                });
            }
            return {results: arr};
        }
    });
};

以下是在调用上述函数之前,HTML中的Select2元素应该是什么样的:

<input id="add-service-select-service" type="hidden" style="width:100%">

要使用所有这些,请调用(在JS中):

window.fetchFromAPI();
window.refreshServicesSelect();

最后,这里有一个JSFiddle,你可以玩类似的东西:http://jsfiddle.net/RVnfn/102/

基本上,在我上面的例子中,我们只是使用ajax来填充小提琴中的window.pills。

希望这会有所帮助:)

如果您知道如何通过Select2 .ajax功能进行回复,请回复,因为这样会有点短。

答案 2 :(得分:0)

这适用于Select2 v4.0.3:

我遇到了同样的问题,并通过触发AJAX调用并使用返回的数据作为初始化数据数据来解决这个问题。

// I used an onClick event to fire the AJAX, but this can be attached to any event.
// Ensure ajax call is done *ONCE* with the "one" method.
$('#mySelect').one('click', function(e) {
    // Text to let user know data is being loaded for long requests.
    $('#mySelect option:eq(0)').text('Data is being loaded...');
    $.ajax({
        type: 'POST',
        url: '/RetrieveDropdownOptions',
        data: {}, // Any data that is needed to pass to the controller
        dataType: 'json',
        success: function(returnedData) {
            // Clear the notification text of the option.
            $('#mySelect option:eq(0)').text('');
            // Initialize the Select2 with the data returned from the AJAX.
            $('#mySelect').select2({ data: returnedData });
            // Open the Select2.
            $('#mySelect').select2('open');
        }
    });
    // Blur the select to register the text change of the option.
    $(this).blur();
});

这对我的想法很有效。希望这可以帮助人们搜索相同的问题。

答案 3 :(得分:0)

在我的情况下,它可以与给定的代码完美配合

$('#itemid').select2({
    cacheDataSource: [],
    closeOnSelect: true,
    minimumInputLength: 3,
    placeholder: "Search Barcode / Name",
    query: function(query) {
        // console.log(query);
        self = this;
        var key = query.term;
        var cachedData = self.cacheDataSource[key];
        if(cachedData) {
            query.callback({results: cachedData});
            return;
        } else {
            $.ajax({
                url: "./includes/getItemSelect2.php",
                data: { value : query.term },
                dataType: 'json',
                type: 'POST',
                success: function(data) {
                    self.cacheDataSource[key] = data;
                    query.callback({results: data});
                }
            });
        }
    },
});

我从ajax返回的数据就是这种形式

<?php
$arr = [
    ["id" => 1, "text" => "Testing"],
    ["id" => 2, "text" => "test2"],
    ["id" => 3, "text" => "test3"],
    ["id" => 4, "text" => "test4"],
    ["id" => 5, "text" => "test5"]
];
echo json_encode($arr);
exit();
?>