В Slim Select управление списком значений строится вокруг внутреннего
состояния инстанса, которое синхронизируется с исходным
<select>. При динамическом добавлении опций важно
учитывать, что библиотека не просто дописывает элементы в DOM, а
обновляет собственную модель данных, после чего пересобирает
интерфейс.
Ключевая особенность: любое изменение набора опций должно выполняться
через API экземпляра Slim Select, а не через прямое манипулирование DOM
<option>.
Инициализация базового инстанса:
const select = new SlimSelect({
select: '#mySelect'
});
После создания инстанса становится доступен набор методов для управления списком значений.
Для добавления новой записи используется метод
addOption. Он позволяет внедрить элемент в список без
полной перезагрузки данных.
Базовый формат:
select.addOption({
text: 'Новая опция',
value: 'new_option'
});
Дополнительные свойства объекта:
text — отображаемый текстvalue — значениеselected — установка выбранного состоянияdisabled — блокировка выбораПример с предустановленным выбором:
select.addOption({
text: 'Москва',
value: 'moscow',
selected: true
});
При добавлении с selected: true библиотека автоматически
обновляет текущее значение селекта.
При необходимости загрузить сразу набор значений эффективнее
использовать пакетное обновление через setData. Это
полностью заменяет текущий список опций.
select.setData([
{ text: 'JavaScript', value: 'js' },
{ text: 'TypeScript', value: 'ts' },
{ text: 'Python', value: 'py' }
]);
Особенность метода заключается в том, что он:
Этот подход предпочтителен при загрузке данных с сервера.
Поведение методов различается принципиально:
| Метод | Поведение |
|---|---|
| addOption | добавляет один элемент без сброса состояния |
| setData | заменяет весь набор опций |
Использование addOption оправдано при инкрементальном
обновлении, например при пользовательском вводе. setData
применяется при полной синхронизации с внешним источником данных.
Частый сценарий — создание новых элементов на основе введённого текста.
const inputValue = 'React';
select.addOption({
text: inputValue,
value: inputValue.toLowerCase()
});
Если требуется избегать дубликатов, предварительно выполняется проверка текущих значений:
const exists = select.data.data.some(item => item.value === 'react');
if (!exists) {
select.addOption({
text: 'React',
value: 'react'
});
}
Slim Select часто используется вместе с удалёнными API. В таком случае новые опции добавляются после завершения запроса.
fetch('/api/languages')
.then(res => res.json())
.then(data => {
data.forEach(item => {
select.addOption({
text: item.name,
value: item.code
});
});
});
Такой подход позволяет постепенно расширять список, не блокируя интерфейс.
При частичной перезагрузке списка важно сохранить текущее состояние выбора.
const currentValue = select.selected();
select.setData(newData);
select.set(currentValue);
Механика:
Этот паттерн используется при фильтрации данных или смене категорий.
При динамическом добавлении можно управлять доступностью элементов:
select.addOption({
text: 'Недоступный пункт',
value: 'disabled_item',
disabled: true
});
Также можно изменять доступность в зависимости от состояния приложения:
select.addOption({
text: 'Платный тариф',
value: 'premium',
disabled: !user.isPremium
});
В случаях, когда требуется полное обновление структуры, используется комбинация очистки и установки нового набора данных:
select.setData([]);
или полная пересборка:
select.destroy();
new SlimSelect({
select: '#mySelect',
data: newData
});
destroy полностью удаляет инстанс и возвращает
стандартное поведение <select>.
При работе с динамическими опциями часто возникают следующие проблемы:
document.querySelector('#mySelect').innerHTML += ...
Такой подход не синхронизируется с внутренним состоянием Slim Select и приводит к рассинхронизации интерфейса.
Отсутствие проверки уникальности вызывает дублирование опций и некорректное поведение поиска внутри списка.
При полной замене данных без сохранения состояния выбранный элемент сбрасывается. Решается сохранением значения перед обновлением.
Динамическое добавление часто привязывается к событиям интерфейса:
button.addEventListener('click', () => {
select.addOption({
text: 'Добавлено по клику',
value: Date.now().toString()
});
});
Или к полю ввода:
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
select.addOption({
text: e.target.value,
value: e.target.value
});
}
});
При массовом добавлении элементов по одному вызов
addOption может быть неэффективен. В таких случаях
предпочтительнее сформировать массив и применить
setData:
const prepared = apiResult.map(item => ({
text: item.title,
value: item.id
}));
select.setData(prepared);
Это снижает количество перерисовок и ускоряет обновление интерфейса.
После добавления или замены данных Slim Select автоматически обновляет внутренний список, однако при сложных сценариях (фильтрация, каскадные селекты) требуется ручная синхронизация:
select.set(select.selected());
Этот вызов гарантирует, что UI и модель данных находятся в одном состоянии после серии изменений.