如何通过 ajax 预加载数组并将其用于 select2?

How to pre-load an array via ajax and use it for select2?

我的一般问题是我想要一个 Javascript 变量,然后我将其与 select2 一起使用,以准备 select 倍数的选项。我有一个相当大的数组(7000 个对象),只想将其存储在一个变量中,而不是不断地用搜索词轮询服务器。这是我得到的。

HTML就是:

<input type="hidden" id="group_a" multiple="multiple" placeholder="Select at least two treatments">

现在,当我直接写入变量时,一切都按预期工作:

var treatments = [{id: 1, text: "you"}, {id: 2, text: "me"}];
$("#group_a").select2({
    data: treatments,
    minimumInputLength: 1,
    multiple: true,
    closeOnSelect: false,
    width: "660px"
});

但是,当我使用 ajax 加载数组时,事情变得很奇怪。我的代码:

$.ajax({
    url: '/funny/url',
}).done(function(data) {
    treatments = data.choices;
});

除非我使用调试器单步执行代码,然后它按预期工作,否则我往往会收到以下错误。那么这会不会是一个时间问题?

uncaught exception: query function not defined for Select2 group_a

我的完整 javascript 如下所示,我还准备了一个显示相同错误的 fiddle

$(document).ready(function() {
    var treatments;
    $.ajax({
        url: '/funny/url',
    }).done(function(data) {
        treatments = data.choices;
    });
    $("#group_a").select2({
        data: treatments,
        minimumInputLength: 1,
        multiple: true,
        closeOnSelect: false,
        width: "960px"
    });
});

ajax 调用是异步的,因此在检测 Select2 控件时,treatments 仍未定义。

您可以执行以下操作:

$(document).ready(function() {
    $.ajax({
        url: '/funny/url',
    }).done(function(data) {
        $("#group_a").select2({
            data: data.choices,
            minimumInputLength: 1,
            multiple: true,
            closeOnSelect: false,
            width: "960px"
        });
    });
});

jsfiddle

不过更好的是,我会执行以下操作。

最初将 treatments 设置为一个空数组,并为 data 选项使用一个函数,这样如果 treatments 被更改,更改将被 Select2 控件拾取。这样,您可以立即检测 Select2 控件,然后使用 ajax 调用返回的数据更新 treatments。此外,您可以先禁用 Select2 控件,然后在 ajax 调用 returns.

时启用它
$(document).ready(function() {
    var treatments = [];
    $.ajax({
        url: '/funny/url',
    }).done(function(data) {
        treatments = data.choices;
        $("#group_a").select2('enable', true);
    });
    $("#group_a").select2({
        data: function() { return { results: treatments }; },
        minimumInputLength: 1,
        multiple: true,
        closeOnSelect: false,
        width: "960px"
    }).select2('enable', false);
});

jsfiddle

第三个选项是保留原始代码,但使 ajax 调用同步。我建议不要那样做。当您进行 ajax 同步调用时,您会锁定整个浏览器。

这是我的解决方案。感谢@John S 的初始方法,但我无法让 select2 格式化程序解析我的数组。 Select2 框会告诉我 'no results found.' 我最终 运行 一个 for 循环遍历我的数组并写出 :id, :text 哈希。

从我的 json ajax 调用开始是一个字符串数组 'terms':

// localhost:3000/search/typeahead_terms_all.json    
[
        "Super Term",
        "cool term",
        "killer term",
        "awesome term",
        "try term",
        "param term",
        "try name",
        "Academic Year",
        "grade average",
        "Hello Term",
        "Academic Calendar",
        "kinda cool term",
        "My Term",
    ]

然后 javascript:

$(document).ready(function() {
  var term_names_array = [];
  $.ajax({
    url: '/search/typeahead_terms_all',
  }).done(function(data) {
    // Here I iterate through my array of strings and write out the hash select2 needs
    for (index = 0; index < data.length; ++index) {
      term_names_array.push({ id: index, text: data[index] });
    }
    $('.report_term_input').select2('enable', true);
  });
  $('.report_term_input').select2({
    dataType: 'json',
    data: term_names_array,
    multiple: true,
    width: "500px"
  });
});