В основе Slim Select лежит модель, при которой DOM-элемент
<select> выступает источником состояния, а библиотека
синхронизирует визуальный слой с внутренним представлением данных. Любое
динамическое изменение опций требует обновления двух уровней: структуры
данных и отрисованного интерфейса.
Ключевой принцип заключается в том, что Slim Select не просто «рисует» список, а поддерживает внутренний массив элементов, который используется для фильтрации, выбора и отображения состояния. Поэтому прямые манипуляции с DOM без уведомления экземпляра приводят к рассинхронизации.
Одним из базовых механизмов обновления является полная перезагрузка набора данных. Этот подход используется при переходе между контекстами, фильтрации или загрузке данных с сервера.
Метод setData полностью заменяет текущие опции:
const select = new SlimSelect({
select: '#cities'
});
select.setData([
{ text: 'Алматы', value: 'almaty' },
{ text: 'Астана', value: 'astana' },
{ text: 'Шымкент', value: 'shymkent' }
]);
После вызова происходит:
Особенность заключается в том, что выбранные значения автоматически проверяются на соответствие новым данным. Если значение отсутствует в новом массиве, оно удаляется из состояния.
При необходимости инкрементального расширения списка используется добавление отдельных элементов без полной перезагрузки данных.
Типовой сценарий — динамическое добавление нового значения после пользовательского ввода:
select.addOption({ text: 'Караганда', value: 'karaganda' });
При добавлении выполняется:
В мультиселекте добавленный элемент становится доступным сразу для выбора без дополнительной перерисовки всей структуры.
Удаление элементов требует аккуратного обращения с состоянием выбранных значений. Slim Select синхронизирует выбранные элементы с доступными опциями, поэтому удаление выбранного значения автоматически влияет на модель.
Удаление одного элемента:
select.removeOption('astana');
Очистка всего набора данных:
select.setData([]);
Или полная очистка выбора без изменения списка:
select.set([]);
При удалении важно учитывать:
Манипуляции с выбором напрямую связаны с синхронизацией состояния. Slim Select предоставляет метод установки значений программно.
select.set(['almaty', 'shymkent']);
Для одиночного выбора:
select.set('almaty');
Механика работы:
<select>;Если значение отсутствует в списке, оно игнорируется без ошибки, что позволяет безопасно применять серверные данные.
Частый сценарий динамического обновления связан с загрузкой данных через API. Slim Select не навязывает встроенный AJAX-слой, но легко интегрируется с fetch-запросами.
fetch('/api/cities')
.then(res => res.json())
.then(data => {
select.setData(
data.map(item => ({
text: item.name,
value: item.id
}))
);
});
При асинхронной загрузке важно учитывать временные состояния:
Расширенный вариант — частичное обновление без сброса выбора:
const current = select.selected();
fetch('/api/cities')
.then(res => res.json())
.then(data => {
select.setData(data);
const valid = current.filter(v =>
data.some(item => item.value === v)
);
select.set(valid);
});
При сложных интерфейсах требуется комбинировать добавление, удаление и обновление опций без полной перезагрузки списка.
Сценарий синхронизации с сервером:
function syncOptions(serverData) {
const existing = select.data();
const toAdd = serverData.filter(
s => !existing.some(e => e.value === s.id)
);
const toRemove = existing.filter(
e => !serverData.some(s => s.id === e.value)
);
toRemove.forEach(item => {
select.removeOption(item.value);
});
toAdd.forEach(item => {
select.addOption({
text: item.name,
value: item.id
});
});
}
Такой подход позволяет минимизировать перерисовки и сохранять UI в стабильном состоянии.
При динамическом обновлении данных важно управлять визуальными состояниями компонента. Slim Select не навязывает отдельного API для состояний, поэтому используются косвенные методы.
Пустое состояние:
select.setData([]);
Имитация загрузки:
select.disable();
После загрузки:
select.enable();
Типовая модель поведения:
При динамическом обновлении важно учитывать встроенный поиск Slim Select. После изменения данных индекс поиска пересобирается автоматически, однако при сложных сценариях требуется дополнительная логика.
Пример фильтрации:
select.setData(
allItems.filter(item =>
item.name.toLowerCase().includes(query.toLowerCase())
)
);
При частых обновлениях (например, live search) применяется debounce, чтобы избежать перегрузки:
let timeout;
input.addEventListener('input', (e) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
upd ateData(e.target.value);
}, 300);
});
Неправильная работа с обновлением данных часто приводит к неконсистентному состоянию интерфейса.
Прямое изменение DOM без API Slim Select
document.querySelector('#select').innerHTML += '<option>...</option>';
Такой подход нарушает внутренний индекс библиотеки.
Несоответствие выбранных значений новым данным
После setData старые значения могут оставаться в модели,
если не выполнена проверка валидности.
Частые повторные setData при загрузке
Многократные вызовы приводят к миганию интерфейса и потере фокуса.
Игнорирование асинхронного состояния
Одновременные запросы могут перезаписать друг друга, если не контролировать порядок ответов сервера.
В SPA-архитектурах Slim Select часто используется вместе с реактивными слоями, где обновление данных происходит при изменении состояния приложения.
Типовой паттерн:
Пример интеграции:
store.subscribe(state => {
select.setData(state.options);
select.set(state.selected);
});
Такой подход обеспечивает предсказуемую модель поведения при любых изменениях данных.