Select2 提供了与之前 3.5.x 版本有限的向后兼容性,使得用户可以更高效地跨版本迁移并获取最新功能。对于许多较大的更改,例如自定义数据适配器工作方式的变更,创建了兼容模块来协助升级过程。但不建议依赖这些兼容模块,因为它们将在未来的版本中被移除,不过它们可以使重大更改的升级更加容易。
如果你使用的是 Select2 的完整版本(select2.full.js
),你会自动收到重大破坏性更改的通知,并且兼容模块将自动应用,以确保你的代码仍能按照预期运行。
兼容模块仅包含在 Select2 的完整构建版本完整版本中。这些文件名以.full.js
结尾,兼容模块的前缀为select2/compat
.
在 Select2 的旧版本中,如果你想使用一些高级功能,例如使用远程数据源或允许用户添加自己的标签,则推荐使用<input type="hidden">
标签。这会导致一个不幸的副作用,即服务器不会像标准<select>
元素那样将 Select2 的数据作为数组接收,而是接收到一个包含逗号分隔字符串的字符串。代码库最终充满了针对隐藏输入的特殊情况,而使用 Select2 的库也必须绕过它引起的差异。
在 Select2 4.0 中,<select>
元素支持所有核心选项,对旧版<input type="hidden">
的支持已被弃用。这意味着如果你之前声明了一个带有预选选项的 AJAX 字段,类似如下内容:
<input type="hidden" name="select-boxes" value="1,2,4,6" />
它需要重新创建为一个<select>
元素,并带有一些具有<option>
标签的value
属性匹配旧值的选项:
<select name="select-boxes" multiple="multiple">
<option value="1" selected="selected">Select2</option>
<option value="2" selected="selected">Chosen</option>
<option value="4" selected="selected">selectize.js</option>
<option value="6" selected="selected">typeahead.js</option>
</select>
你创建的选项应设置selected="selected"
,以便 Select2 和浏览器知道它们应该被选中。选项的value
属性也应设置为服务器返回结果时的值,这样 Select2 可以将其高亮显示为已选中。选项中的文本还应反映该选项默认显示的值。
在 Select2 的旧版本中,matcher
回调会在每个层级处理选项,这限制了你在显示结果时的控制力,尤其是在存在嵌套数据的情况下。matcher
函数只能接收到单个选项,即使它是嵌套选项,也没有提供任何上下文信息。
使用新的匹配函数,现在只对根级别的选项进行匹配,而匹配器应限制其包含的子选项的结果。这允许开发人员自定义如何显示组内选项,并修改结果的返回方式。
matcher
回调的包装器为了保持向后兼容,创建了一个包装函数,允许将旧式匹配函数转换为新风格。
此包装函数仅包含在 Select2 的完整版本中。你可以从select2/compat/matcher
模块中获取该函数,它只需封装旧的匹配函数即可。
对于仅接受搜索词和选项文本作为参数的匹配器来说,这样做是可行的。如果你的匹配器依赖第三个参数(表示原始
<option>
标签的 jQuery 元素),那么你可能需要稍微修改你的匹配器,使其能够接收传入的完整 JavaScript 数据对象。你仍然可以通过数据对象使用data.element
属性中。
在 Select2 的最近版本中,占位符只能应用于<select>
中第一个(通常是默认)选项,并且该选项必须为空白。placeholderOption
选项被添加到 Select2 中,以允许使用select
标签的用户选择另一个选项,通常是一个自动生成的、具有不同值的选项。
的placeholder
选项现在还可以接受一个对象而不仅仅是字符串。这取代了旧版的placeholderOption
,因为现在可以将对象的id
设置为value
属性的<option>
标签。
对于如下所示的 select 元素,其中第一个选项(值为-1
)是占位符选项:
<select>
<option value="-1" selected="selected">Select an option</option>
<option value="1">Something else</option>
</select>
以前你需要通过placeholderOption
来获取占位符选项,但现在你可以通过placeholder
时,Select2 将自动显示占位符,而这正是默认情况下的值。这并不会破坏 Select2 旧功能中占位符选项默认为空白的功能。id
.
$("select").select2({
placeholder: {
id: "-1",
placeholder: "Select an option"
}
});
属性来实现。-1
当 select 的值为
在 Select2 的旧版本中,选项是按照被选择的顺序显示的。在某些情况下,当 Select2 被用在<select>
元素上时,服务器接收到的选择顺序并不总是与显示的选项顺序一致,这在顺序重要的场景下会引起困惑。
现在 Select2 将按照发送到服务器的顺序来排列已选中的选项。
在设计 Select2 4.0 的未来选项集时,特别注意确保最常用的选项得以保留。大多数情况下,Select2 常用选项仍可通过其旧名称引用,但确实也发生了一些变化,具体如下。
initSelection
在 Select2 4.0 中已弃用。此功能已被另一个选项取代,仅在完整构建版本的Select2中。
过去,每当您想要使用自定义数据适配器(例如 AJAX 或标记)时,您需要帮助 Select2 确定初始选中的值。这通常是通过initSelection
选项实现的,它接受输入的底层数据并将其转换为 Select2 可以使用的数据对象。
现在这由数据适配器在current
方法中处理,该方法允许 Select2 将当前选中的值转换为可以显示的数据对象。默认实现将option
元素的文本和值转换为数据对象,适用于大多数情况。旧的initSelection
选项的一个示例如下所示,它将选中选项的值转换为包含id
和text
与所选值匹配的数据对象。
{
initSelection : function (element, callback) {
var data = [];
$(element.val()).each(function () {
data.push({id: this, text: this});
});
callback(data);
}
}
使用新的自定义数据适配器的current
方法时,每当 Select2 需要获取当前选中选项列表时都会调用此方法。这不同于旧的因为它只被调用一次,因此在处理数据时可能相对较慢(例如从远程数据源)。initSelection
in that it was only called once, so it could suffer from being relatively slow to process the data (such as from a remote data source).
$.fn.select2.amd.require([
'select2/data/array',
'select2/utils'
], function (ArrayData, Utils) {
function CustomData ($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.current = function (callback) {
var data = [];
var currentVal = this.$element.val();
if (!this.$element.prop('multiple')) {
currentVal = [currentVal];
}
for (var v = 0; v < currentVal.length; v++) {
data.push({
id: currentVal[v],
text: currentVal[v]
});
}
callback(data);
};
$("#select").select2({
dataAdapter: CustomData
});
}
数据适配器的新current
数据适配器的方法与旧的initSelection
方法类似,但有三个显著区别。第一个也是最重要的区别是它会在需要当前选择项时被调用以确保 Select2 始终显示最准确和最新的数据。无论 Select2 附加到何种类型的元素,无论其支持单个还是多个选择,传递给回调函数的必须是一个数组,即使它只包含一个选择项.
最后一点是只有一个参数,即使用最新数据执行的回调函数,并且 Select2 当前附加到的元素可在类本身上作为this.$element
.
如果您只需要加载一次初始选项,之后让 Select2 处理选中状态,那么您不需要使用自定义数据适配器。您可以自行创建<option>
标签,Select2 会自动检测到这些更改。
var $element = $('select').select2(); // the select element you are working with
var $request = $.ajax({
url: '/my/remote/source' // wherever your data is actually coming from
});
$request.then(function (data) {
// This assumes that the data comes back as an array of data objects
// The idea is that you are using the same callback as the old `initSelection`
for (var d = 0; d < data.length; d++) {
var item = data[d];
// Create the DOM option that is pre-selected by default
var option = new Option(item.text, item.id, true, true);
// Append it to the select
$element.append(option);
}
// Update the selected options that are displayed
$element.trigger('change');
});
query
在 Select2 4.0 中已弃用。此功能已被另一个选项取代,仅在完整构建版本的Select2中。
过去每次您想将 Select2 连接到不同的数据源时,都需要实现自定义query
和initSelection
方法。这允许 Select2 确定初始选择以及要显示的结果列表,其他所有操作都在内部进行处理,这对大多数人来说已经足够好了。
自定义query
和initSelection
方法已被自定义数据适配器所取代,后者控制 Select2 如何存储和检索将显示给用户的数据。下面提供了旧query
选项的一个示例,即与旧示例相同它生成的结果包含重复一定次数的搜索词。
{
query: function (query) {
var data = {results: []}, i, j, s;
for (i = 1; i < 5; i++) {
s = "";
for (j = 0; j < i; j++) {
s = s + query.term;
}
data.results.push({
id: query.term + i,
text: s
});
}
query.callback(data);
}
}
此功能已被定义了一个同名方法的自定义数据适配器所取代。下面提供了一个可比较的数据适配器作为示例。query
method. The comparable data adapter is provided below as an example.
$.fn.select2.amd.require([
'select2/data/array',
'select2/utils'
], function (ArrayData, Utils) {
function CustomData ($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
var data = {
results: []
};
for (var i = 1; i < 5; i++) {
var s = "";
for (var j = 0; j < i; j++) {
s = s + params.term;
}
data.results.push({
id: params.term + i,
text: s
});
}
callback(data);
};
$("#select").select2({
dataAdapter: CustomData
});
}
数据适配器的新query
方法与初始化 Select2 时传入的旧query
选项非常类似。旧的query
参数与新params
的参数几乎相同,用于查询的内容,现在回调函数作为第二个参数传入。
以前,Select2 提供了多个用于格式化结果列表和已选选项的选项,通常称为“格式化器”,使用的是formatSelection
和formatResult
选项。由于“格式化器”也曾用于本地化等功能,而这也发生了变化因此它们被重命名为templateSelection
和templateResult
并且它们的签名也发生了变化。
从早期版本的 Select2 迁移时,您应该查阅更新后的模板文档了解结果和选择项的相关文档。
createSearchChoice
此方法已重命名为createTag
从早期版本的 Select2 迁移时,请参阅选项创建的相关文档。
的createSearchChoicePosition
选项已被移除,取而代之的是insertTag
函数。新标签默认添加到列表底部。
insertTag: function (data, tag) {
// Insert the tag at the end of the results
data.push(tag);
}
selectOnBlur
此方法已重命名为selectOnClose
.
id
和text
属性被严格强制执行过去处理数组和 AJAX 数据时,Select2 允许在多个地方设置自定义id
函数或属性,包括 Select2 初始化时和返回远程数据时。这使得 Select2 可以更好地集成那些不一定使用id
属性来表示对象唯一标识符的现有数据源。
Select2 不再支持使用自定义id
或text
但提供了转换为预期格式的集成点:
以前,Select2 支持将数组数据定义为符合 AJAX 响应签名的对象。可以指定一个text
属性,将给定属性映射到各个对象上的text
属性。现在可以在初始化 Select2 时使用以下 jQuery 代码将旧text
和id
属性映射到新属性。
var data = $.map([
{
pk: 1,
word: 'one'
},
{
pk: 2,
word: 'two'
}
], function (obj) {
obj.id = obj.id || obj.pk;
obj.text = obj.text || obj.word;
return obj;
});
这将生成一个数据对象数组,其中的id
与现有属性匹配的属性pk
属性和text
与现有属性匹配的属性word
属性。
上面提供的相同代码可以在AJAX调用的processResults
方法中使用,以将属性映射到那里。
在Select2的早期版本中,提供给用户默认消息可以本地化为网站所使用的语言。Select2默认只带有英语语言,但提供了社区贡献的翻译来适配许多常见语言。许多格式化函数已经移动到了language
选项,并且格式化函数的签名也已经更改以支持未来的新增内容。
data-*
属性过去,Select2仅支持使用data-*
HTML属性声明部分选项。现在Select2支持使用HTML属性声明所有选项,使用的是文档中指定的格式。.
以前你可以通过使用data-ajax-url
HTML属性来声明用于AJAX请求的URL。虽然Select2仍然允许这样做,但现在应该使用的新属性是data-ajax--url
。旧属性的支持将在Select2 4.1中被移除。
虽然没有被文档记录,但也可以通过使用data-select2-tags
HTML属性并传入一个JSON格式的对象数组来提供可能的标签列表。由于在4.0中指定标签的方法已经改变,你现在应该使用data-data
属性来提供对象数组,它映射到数组数据选项。你也应通过在对象上设置data-tags="true"
来启用标签功能,以便保持用户创建自己选项的能力。
如果你之前将标签列表声明为:
<select data-select2-tags='[{"id": "1", "text": "One"}, {"id": "2", "text": "Two"}]'></select>
...那么你现在应该将其声明为...
<select data-data='[{"id": "1", "text": "One"}, {"id": "2", "text": "Two"}]' data-tags="true"></select>
由于Select2现在对所有数据源都使用<select>
元素,有几个通过调用.select2()
可用的方法已不再需要。
.select2("val")
的"val"
方法已被弃用,并将在Select2 4.1中被移除。该弃用方法不再包含triggerChange
参数。
你应该直接在底层.val
元素上调用<select>
。如果你需要第二个参数(triggerChange
),你也应在元素上调用.trigger("change")
。
$("select").val("1").trigger("change"); // instead of $("select").select2("val", "1");
.select2("enable")
Select2会尊重底层select元素的disabled
属性。为了启用或禁用Select2,你应该在.prop('disabled', true/false)
元素上进行调用。旧方法的支持将在Select2 4.1中被完全移除。<select>
element. Support for the old methods will be completely removed in Select2 4.1.
$("select").prop("disabled", true); // instead of $("select").enable(false);