
本文详解如何正确调用 ChoicesJS 的 setChoices() 实例方法,向已初始化的下拉选择器动态追加选项,避免因访问方式错误导致的“undefined is not a function”等常见报错。
本文详解如何正确调用 choicesjs 的 `setchoices()` 实例方法,向已初始化的下拉选择器动态追加选项,避免因访问方式错误导致的“undefined is not a function”等常见报错。
在使用 ChoicesJS 时,一个常见误区是:误以为可通过原生 DOM 元素(如 document.getElementById('random-select'))直接调用 setChoices() 或 setValue() 方法。实际上,setChoices() 是 Choices 实例的方法,而非 HTML 元素的方法——因此必须先保存初始化时返回的实例引用,再通过该实例调用。
✅ 正确做法:保存并复用 Choices 实例
首先,在初始化时将 new Choices(...) 的返回值赋给一个变量(如 choices),后续所有动态操作均基于该变量:
<!-- 引入 ChoicesJS 样式与脚本 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js@10.2.0/public/assets/styles/choices.min.css"><script src="https://cdn.jsdelivr.net/npm/choices.js@10.2.0/public/assets/scripts/choices.min.js"></script><select id="random-select"></select><button id="append-choices">Append new data to select</button>
// ✅ 正确初始化并保存实例
const selectEl = document.getElementById('random-select');
const choices = new Choices(selectEl, {
removeItemButton: true,
duplicateItemsAllowed: false,
searchEnabled: true,
searchChoices: true,
// 注意:若需插入含 HTML 的 label,请启用 allowHTML: true
});
// ✅ 动态追加选项(支持单个或多个)
const append = () => {
choices.setChoices([
{ value: '1', label: 'Option One' },
{ value: '2', label: 'Option Two' }
], 'value', 'label', false); // 第4个参数 false 表示「追加」而非「替换」
};
document.getElementById('append-choices').addEventListener('click', append);
? 关键参数说明:
setChoices(choicesArray, valueKey, labelKey, replace)
- choicesArray: 选项数组,每个对象需包含 value 和 label 字段(或自定义键名);
- valueKey / labelKey: 指定数据中用于 value 和 label 的属性名(默认为 'value' 和 'label');
- replace: true 时清空原有选项并重置;false 时追加(即实现“append”语义)。
⚠️ 常见错误与注意事项
- ❌ 错误写法:selectEl.setChoices(...) → selectEl 是原生
- ❌ 错误写法:selectEl.choices.setValue(...) → choices 属性并不存在于 DOM 元素上;
- ✅ 正确前提:必须持有 Choices 实例引用,且确保 setChoices() 调用发生在实例初始化之后;
- ? 版本兼容性:setChoices() 自 v10.0+ 稳定支持,建议使用 v10.2.0 或更高版本;
- ? 追加 vs 替换:第四个参数 replace 控制行为——传 false 即可安全追加,无需手动读取当前选项再合并。
? 进阶提示:批量追加 + 防重复
若需避免重复添加相同 value 的选项,可先获取当前已存在选项,再过滤后追加:
const appendUnique = (newOptions) => {
const currentValues = choices.getValue(true); // 返回字符串数组,如 ['1', '2']
const filtered = newOptions.filter(opt => !currentValues.includes(opt.value));
if (filtered.length > 0) {
choices.setChoices(filtered, 'value', 'label', false);
}
};
掌握 setChoices(..., ..., ..., false) 这一模式,即可稳健实现运行时动态扩展 ChoicesJS 下拉选项,兼顾可维护性与用户体验。











