Slim Select предоставляет событийную модель, основанную на подписке на изменения состояния компонента и жизненный цикл взаимодействия пользователя с выпадающим списком. Архитектура событий построена вокруг принципа реактивности: любое значимое действие внутри компонента транслируется наружу через набор предопределённых колбэков, что позволяет интегрировать библиотеку в сложные интерфейсы без необходимости модификации её внутреннего кода.
События в Slim Select не являются DOM-событиями в классическом понимании. Это внутренние хук-точки, которые вызываются в строго определённые моменты жизненного цикла компонента. Подписка осуществляется через конфигурационный объект при инициализации экземпляра.
Базовая структура подключения событий:
new SlimSelect({
select: '#example',
events: {
afterChange: (newVal) => {},
beforeOpen: () => {},
afterOpen: () => {},
beforeClose: () => {},
afterClose: () => {}
}
});
Каждый обработчик получает строго определённый набор аргументов, зависящий от типа события, что позволяет избегать неоднозначности состояния.
Событие afterChange вызывается после того, как значение
<select> было изменено и внутреннее состояние
компонента синхронизировано.
new SlimSelect({
select: '#cities',
events: {
afterChange: (info) => {
console.log(info);
}
}
});
Типичная структура info:
multiple: trueОсобенность механизма заключается в том, что событие срабатывает уже после обновления DOM и внутреннего state-слоя Slim Select, что делает его безопасным для побочных эффектов: AJAX-запросов, синхронизации с формами, обновления UI.
Событие beforeChange выполняется до применения нового
значения. Оно позволяет перехватывать изменение и при необходимости
отменять его.
new SlimSelect({
select: '#countries',
events: {
beforeChange: (newValue, oldValue) => {
if (newValue === 'restricted') {
return false;
}
}
}
});
Возвращение false блокирует обновление состояния. Это
ключевой механизм валидации и бизнес-логики на уровне компонента.
Характерные сценарии использования:
Событие beforeOpen вызывается непосредственно перед
отображением dropdown-списка. На этом этапе DOM уже готовится к рендеру,
но визуальное открытие ещё не произошло.
new SlimSelect({
select: '#products',
events: {
beforeOpen: () => {
console.log('dropdown will open');
}
}
});
Данный хук используется для:
При необходимости можно прервать открытие, вернув
false.
Событие afterOpen срабатывает после того, как dropdown
полностью отображён и доступен для взаимодействия.
new SlimSelect({
select: '#users',
events: {
afterOpen: () => {
console.log('opened');
}
}
});
На этом этапе можно безопасно:
Особенность заключается в том, что все DOM-элементы уже созданы и присутствуют в дереве, поэтому любые операции с ними выполняются без риска гонок состояния.
Событие beforeClose вызывается перед закрытием списка.
Оно аналогично beforeOpen, но работает в обратном
направлении жизненного цикла.
new SlimSelect({
select: '#tags',
events: {
beforeClose: () => {
console.log('closing dropdown');
}
}
});
Типовые сценарии:
Возврат false блокирует закрытие, что позволяет
удерживать UI в открытом состоянии при необходимости.
Событие afterClose фиксирует момент полного завершения
закрытия компонента. DOM-элементы списка уже удалены или скрыты, а
внутренние состояния синхронизированы.
new SlimSelect({
select: '#categories',
events: {
afterClose: () => {
console.log('closed');
}
}
});
Используется для:
Событие search активируется при вводе текста в поле
поиска внутри dropdown. Оно является ключевым для реализации кастомной
фильтрации и интеграции с серверным поиском.
new SlimSelect({
select: '#searchable',
events: {
search: (searchTerm) => {
console.log(searchTerm);
}
}
});
Часто используется для:
При работе с серверным поиском важным аспектом является управление асинхронностью, так как Slim Select не блокирует поток выполнения и не навязывает модель загрузки данных.
Событийная модель Slim Select построена таким образом, что последовательность вызовов строго детерминирована:
beforeChange → изменение состояния →
afterChangebeforeOpen → рендер → afterOpenbeforeClose → скрытие → afterCloseТакая структура позволяет выстраивать предсказуемую логику управления интерфейсом, исключая необходимость ручного отслеживания DOM-изменений.
Особое значение имеет разделение на «до» и «после» события, которое формирует контрольную точку между намерением пользователя и фактическим изменением состояния.
Механизм отмены реализован через возврат false в
beforeChange, beforeOpen,
beforeClose. Это позволяет внедрять бизнес-правила без
необходимости вмешательства в ядро библиотеки.
Пример комбинированной логики:
new SlimSelect({
select: '#roles',
events: {
beforeChange: (newVal) => {
if (newVal === 'admin' && !window.isAllowed) {
return false;
}
},
beforeOpen: () => {
if (window.locked) {
return false;
}
}
}
});
Такая модель делает Slim Select предсказуемым инструментом в больших приложениях, где контроль состояния должен быть централизован.
События Slim Select не являются асинхронными по своей природе, однако внутри обработчиков возможно выполнение асинхронных операций. Это создаёт необходимость учитывать момент фиксации состояния.
Например, при использовании search для серверной
фильтрации:
new SlimSelect({
select: '#async',
events: {
search: async (term) => {
const res = await fetch(`/api?q=${term}`);
const data = await res.json();
// обновление опций выполняется отдельно
}
}
});
Важно учитывать, что Slim Select не ожидает завершения промисов и не синхронизирует их автоматически с UI.
При сложных сценариях взаимодействия событий возможны каскадные
вызовы, особенно при программном изменении значения, которое может
повторно инициировать afterChange. Это требует контроля за
рекурсивными обновлениями состояния.
Типичный паттерн защиты:
let internalUpdate = false;
new SlimSelect({
select: '#cascade',
events: {
afterChange: (val) => {
if (internalUpdate) return;
internalUpdate = true;
// программное изменение
// которое снова вызовет afterChange
internalUpdate = false;
}
}
});
Такая техника предотвращает бесконечные циклы обновлений.
Событийная система Slim Select выступает не только механизмом реагирования, но и интеграционным слоем между UI-компонентом и внешней бизнес-логикой. Через неё реализуются:
Архитектурно события образуют контракт между библиотекой и приложением, где Slim Select гарантирует порядок вызовов, а приложение определяет реакцию на них.