我觉得上面的答案需要更好的演示。 Select2 4.0.0 introduces 能够做自定义adapters。使用 ajax: {} 技巧,我创建了一个直接使用本地 JSON 的自定义 dataAdapter jsonAdapter。另请注意 Select2 的 4.0.0 版本如何使用大 JSON 字符串获得令人印象深刻的性能。我使用了online JSON generator 并创建了 10,000 个名称作为测试数据。然而,这个例子非常混乱。虽然这可行,但我希望有更好的方法。
在这里查看完整的小提琴:http://jsfiddle.net/a8La61rL/
$.fn.select2.amd.define('select2/data/customAdapter', ['select2/data/array', 'select2/utils'],
function (ArrayData, Utils) {
function CustomDataAdapter($element, options) {
CustomDataAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomDataAdapter, ArrayData);
CustomDataAdapter.prototype.current = function (callback) {
var found = [],
findValue = null,
initialValue = this.options.options.initialValue,
selectedValue = this.$element.val(),
jsonData = this.options.options.jsonData,
jsonMap = this.options.options.jsonMap;
if (initialValue !== null){
findValue = initialValue;
this.options.options.initialValue = null; // <-- set null after initialized
}
else if (selectedValue !== null){
findValue = selectedValue;
}
if(!this.$element.prop('multiple')){
findValue = [findValue];
this.$element.html(); // <-- if I do this for multiple then it breaks
}
// Query value(s)
for (var v = 0; v < findValue.length; v++) {
for (var i = 0, len = jsonData.length; i < len; i++) {
if (findValue[v] == jsonData[i][jsonMap.id]){
found.push({id: jsonData[i][jsonMap.id], text: jsonData[i][jsonMap.text]});
if(this.$element.find("option[value='" + findValue[v] + "']").length == 0) {
this.$element.append(new Option(jsonData[i][jsonMap.text], jsonData[i][jsonMap.id]));
}
break;
}
}
}
// Set found matches as selected
this.$element.find("option").prop("selected", false).removeAttr("selected");
for (var v = 0; v < found.length; v++) {
this.$element.find("option[value='" + found[v].id + "']").prop("selected", true).attr("selected","selected");
}
// If nothing was found, then set to top option (for single select)
if (!found.length && !this.$element.prop('multiple')) { // default to top option
found.push({id: jsonData[0][jsonMap.id], text: jsonData[0][jsonMap.text]});
this.$element.html(new Option(jsonData[0][jsonMap.text], jsonData[0][jsonMap.id], true, true));
}
callback(found);
};
CustomDataAdapter.prototype.query = function (params, callback) {
if (!("page" in params)) {
params.page = 1;
}
var jsonData = this.options.options.jsonData,
pageSize = this.options.options.pageSize,
jsonMap = this.options.options.jsonMap;
var results = $.map(jsonData, function(obj) {
// Search
if(new RegExp(params.term, "i").test(obj[jsonMap.text])) {
return {
id:obj[jsonMap.id],
text:obj[jsonMap.text]
};
}
});
callback({
results:results.slice((params.page - 1) * pageSize, params.page * pageSize),
pagination:{
more:results.length >= params.page * pageSize
}
});
};
return CustomDataAdapter;
});
var jsonAdapter=$.fn.select2.amd.require('select2/data/customAdapter');