Приоритеты конфигурации

Конфигурация экземпляра формируется из нескольких источников, которые накладываются друг на друга по строго определённой системе приоритетов. Поведение библиотеки определяется не только объектом параметров, переданным при инициализации, но и значениями, заданными в DOM, дефолтными настройками, а также динамическими изменениями состояния после создания экземпляра. Понимание порядка применения этих источников критично для предсказуемой работы компонентов.

На нижнем уровне находится встроенный набор дефолтных параметров. Эти значения определяют поведение библиотеки в случае, если разработчик не передал никакой конфигурации.

Дефолтные настройки включают:

  • поведение поиска
  • режим мультивыбора
  • параметры сортировки
  • ограничения на количество элементов
  • визуальные опции интерфейса

Каждый параметр имеет заранее заданное значение, которое гарантирует работоспособность компонента без дополнительной конфигурации. Эти значения не зависят от контекста и всегда применяются первыми при построении внутреннего состояния экземпляра.

Особенность данного уровня заключается в том, что он не перезаписывается напрямую, а лишь служит фундаментом для последующих слоёв конфигурации.

Атрибуты HTML-элемента как источник конфигурации

Следующий уровень приоритета связан с атрибутами исходного DOM-элемента, на котором инициализируется Choices. При создании экземпляра библиотека анализирует разметку и извлекает доступные параметры.

На этом уровне могут учитываться:

  • placeholder
  • disabled
  • multiple
  • required
  • data-* атрибуты

Значения, заданные в HTML, имеют более высокий приоритет, чем встроенные дефолты. Это означает, что при наличии конфликта между дефолтным значением и значением атрибута DOM, будет выбрано значение из разметки.

Особое значение имеют data-* атрибуты, поскольку они часто используются для передачи кастомных настроек. Их обработка выполняется до применения пользовательского конфигурационного объекта, что делает их промежуточным слоем между статической разметкой и программной конфигурацией.

Конфигурационный объект и его роль

Основной механизм управления поведением экземпляра — объект конфигурации, передаваемый при инициализации.

const instance = new Choices(element, {
  searchEnabled: true,
  removeItemButton: true,
  maxItemCount: 5
});

Этот слой имеет более высокий приоритет, чем DOM-атрибуты и дефолтные значения. При совпадении параметров именно значения из конфигурационного объекта считаются актуальными.

Конфигурационный объект формирует основную логику поведения компонента, включая:

  • включение/выключение поиска
  • управление выбором элементов
  • настройку лимитов
  • поведение при добавлении и удалении значений
  • визуальные режимы отображения

Внутри библиотеки происходит нормализация этого объекта: значения приводятся к ожидаемым типам, отсутствующие поля заменяются дефолтами, а некорректные значения игнорируются или приводятся к безопасным альтернативам.

Приоритет кастомных значений данных

После инициализации экземпляра данные, переданные программно через API, начинают оказывать влияние на состояние компонента. Это включает методы:

  • добавления элементов
  • удаления элементов
  • обновления списка вариантов
  • программного изменения состояния

Эти изменения имеют более высокий приоритет, чем статическая конфигурация, поскольку отражают текущую бизнес-логику приложения.

Например, если установлен maxItemCount, но через API продолжается добавление значений, библиотека может блокировать дальнейшие изменения, даже если они не предусмотрены конфигурацией. Таким образом, динамическое состояние начинает конкурировать с исходными настройками.

Переопределение через внутреннее состояние

В процессе работы экземпляр поддерживает внутреннее состояние, которое может временно перекрывать конфигурационные значения.

К таким состояниям относятся:

  • активный поиск
  • выбранные элементы
  • состояние фокуса
  • режим блокировки ввода
  • состояние раскрытия списка

Эти параметры не всегда напрямую связаны с конфигурацией, но могут изменять поведение в реальном времени. Например, отключение поиска через конфигурацию может быть переопределено состоянием фокуса или программным вызовом методов API.

Внутреннее состояние имеет приоритет выше статических настроек, но ниже прямых вызовов методов управления.

Событийные изменения и их влияние

Система событий в Choices.js также участвует в формировании итогового поведения. Обработчики событий могут вмешиваться в процесс изменения состояния и модифицировать его до фиксации.

Типичные события:

  • добавление элемента
  • удаление элемента
  • открытие списка
  • ввод текста
  • фильтрация результатов

Обработчики событий могут:

  • отменять действие
  • изменять данные до применения
  • влиять на отображение
  • вмешиваться в процесс выбора

При этом логика событий не заменяет конфигурацию напрямую, но может изменять итоговое поведение, создавая эффект перекрытия настроек в конкретных сценариях.

Порядок разрешения конфликтов

При одновременном наличии нескольких источников значения применяется строгая иерархия:

  1. Динамическое состояние и API-вызовы
  2. Обработчики событий
  3. Конфигурация экземпляра
  4. DOM-атрибуты
  5. Значения по умолчанию

Такой порядок обеспечивает предсказуемость: чем ближе источник к текущему времени выполнения, тем выше его приоритет.

Пример конфликта:

  • дефолт: поиск отключён
  • HTML: поиск включён через data-*
  • конфиг: поиск отключён
  • API: включение поиска вручную

Итоговое состояние будет зависеть от последнего активного изменения, то есть API-вызова, поскольку он имеет наивысший приоритет.

Особенности наследования при повторной инициализации

При повторной инициализации на том же DOM-элементе конфигурация не сбрасывается полностью. Внутренние структуры могут сохранять часть состояния, особенно если экземпляр не был корректно уничтожен.

Это приводит к ситуации, когда:

  • старые значения перекрывают новые
  • DOM-атрибуты перестают учитываться
  • конфигурация частично игнорируется

Для предотвращения подобных эффектов внутреннее состояние должно быть полностью очищено перед созданием нового экземпляра, иначе приоритеты конфигурации могут давать неожиданные результаты.

Нормализация и приведение типов

Перед применением конфигурации выполняется этап нормализации. Он влияет на приоритет косвенно, поскольку изменяет сами значения до их участия в иерархии.

На этом этапе:

  • строки приводятся к булевым значениям при необходимости
  • числовые параметры проверяются на валидность
  • массивы фильтруются
  • некорректные поля удаляются

Таким образом, даже высокоприоритетный источник может быть скорректирован, если значение не соответствует ожидаемому типу.

Влияние асинхронных обновлений

Некоторые изменения состояния происходят асинхронно, особенно при работе с удалёнными данными или динамической подгрузкой опций. В таких случаях приоритет конфигурации может временно изменяться.

Асинхронные операции могут:

  • добавлять новые элементы поверх текущей конфигурации
  • изменять порядок отображения
  • обновлять список опций независимо от исходных настроек

Приоритет здесь определяется моментом завершения асинхронной операции: последнее завершённое действие становится актуальным независимо от исходной конфигурации.

Конфигурация как неизменяемый слой

После инициализации конфигурационный объект рассматривается как неизменяемый. Любые изменения поведения не должны напрямую модифицировать исходный объект.

Вместо этого:

  • создаётся внутреннее представление настроек
  • изменения применяются через отдельные структуры состояния
  • конфигурация используется только как базовый шаблон

Это разделение обеспечивает стабильность приоритетов и предотвращает непредсказуемые каскадные изменения.