Select2 - 从 15k 单元格数组创建一个自动完成 select 框

Select2 - create an autocomplete select box from 15k cells array

我正在使用 select2 来创建具有自动完成功能的样式化 select 框。我有 2 个选择,从 json 文件加载数据,或者从 json 创建一个简单的 array 并使用变通方法填充 select 标记。我通读了他们的 api 示例,但显然我遗漏了一些东西。我的目标是创建一个包含许多元素的下拉列表,问题是数据是一个巨大的数组,由大约 15k 个单元格组成。我尝试了使用此代码的解决方法:

HTML:

<select multiple="multiple" data-placeholder="Select item" id="itemsList"> 

JS:

var list = $("#itemsList");
var txt = "";
for(var i=0;i<itemsArray.length;i++){
   txt =txt+ '<option value='+itemsArray[i]+'>'+itemsArray[i]+'</option>';
   }
list.append(txt);

这行得通,但显然 select2 管理起来更有效,因为 "method" 需要好几秒钟才能将数据加载到 DOM

第二种方法是将 json 直接加载到 select2 框中,让框架来管理构建,但这会导致错误:Cannot read property 'slice' of undefinedJSfiddle here

这是代码:
HTML:

<div class="input-group" id="itemContainer"> 
    <label> Select an item: </label>
    <select multiple="multiple" data-placeholder="Items list" id="itemList"> 
    </select>
</div>

JS:

    $("select").select2({
      ajax: {
        //this is a small demo json to illustrate its structure
        url: "https://api.myjson.com/bins/5amne",
        dataType: 'json',
        delay: 0,
        data: function (params) {
          return {
            q: params.term, // search term
            page: params.page
          };
        },
        processResults: function (data, params) {
            console.log(data);
          params.page = params.page || 1;

          return {
            results: data.items,
            pagination: {
              more: (params.page * 30) < data.total_count
            }
          };
        },
        cache: true
      },
      escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
      minimumInputLength: 1,
});

为了对 select2 使用 json,json 格式应该是这样的:

{ results: [ {id:'first', text:'a'}, {id:'second', text: 'b'} ]
  , more: false }

JSON format for jquery-select2 multi with ajax

您当前的 json 格式似乎不正确。我认为您应该更改 json 格式。

您的 processData 函数应该处理自定义数据格式,例如以 select2 可以理解的方式解析它。完成方法如下:

processResults: function (data) {
    var results = $.map(data, function (value, key) {
        return {
            text: key,
            children: $.map(value, function (v) {
                return {
                    id: v,
                    text: v
                };
            })
        };
    });

    return {
        results: results,
    };
},

updated JSFiddle

编辑

如果您希望 select2 为您处理过滤,有两种方法:

  1. 添加服务器端支持;
  2. 在客户端处理一切。

由于您是通过静态 JSON 文件加载数据,因此您需要执行 #2。为此,您首先需要加载所有数据,对其进行解析,然后才初始化 select2 控件。你可以做到 like this:

function processData(data) {
    return $.map(data, function (value, key) {
        return {
            text: key,
            children: $.map(value, function (v) {
                return {
                    id: key + v,
                    text: v
                };
            })
        };
    });
}

function initSelect2(data) {
    $("select").select2({
        data: data
    });
}

$.ajax({
    url: "https://api.myjson.com/bins/1n1rm",
    dataType: 'json',
    cache: true,
    success: function (data) {
        initSelect2(processData(data));
    }
});