Модульная система YModules
применяется к уже готовым блокам, поэтому пригодится вам на последнем этапе разработки.
Допустим, клиентский JavaScript-код вашего сайта уже написан. Теперь код отдельных компонентов можно разместить по контейнерам, называемым модулями
.
Модуль подобен фантику от конфеты, на котором написано её название и который по сути является просто обёрткой. Система модулей, в свою очередь, напоминает корзинку с разными сладостями, из которой удобно доставать приглянувшиеся конфеты, определяя нужную по фантику.
Чтобы понять, для чего нужны модули, вспомним, как обычно связывают между собой объекты, реализующие функциональность сайта.
Рассмотрим пример: объявим на странице блок с формой авторизации и напишем для неё клиентский JavaScript-код. В нём опишем поведение формы: пусть после нажатия на кнопку Submit
авторизационные данные отправляются с помощью Ajax, а не через стандартный form.submit()
.
Допустим, в проекте уже определён специальный компонент кнопка
, для которого задано конкретное поведение. Логически поведение может быть следующим:
По клику совершается некое действие. Действие определяется компонентом, из которого кнопка была вызвана.
Таким образом, форма авторизации должна суметь найти кнопку, вызвать её и слушать событие клика на ней.
Блоки и компоненты тесно связаны и зависят друг от друга, поэтому важно учитывать, готов ли каждый из них для взаимодействия. Модульная система отслеживает готовность всех компонентов за вас и избавляет от необходимости вручную поддерживать зависимости между сущностями в актуальном виде. Это позволяет избегать конфликтов в работе сайта и делает его структуру более логичной.
Две основные функции модуля:
- объявлять себя;
- объявлять, какие модули необходимы для корректной работы данного.
При оформлении формы, к примеру, в виде ymaps-модуля, в нём можно задекларировать зависимость от кнопки. При этом, код формы будет активирован только тогда, когда всё для этого будет готово. В частности, когда кнопка будет готова слушать событие клика на себе.
Напишем для примера код модуля. Для начала объявим модуль с помощью метода define()
и назовём его A
:
modules.define(
'A'
);
Объявим также, что наш модуль зависит от модулей B
и C
:
modules.define(
'A',
['B', 'C'],
);
Опишем код модуля A
в анонимной функции. Код модулей B
и C
придёт в эту функцию в виде параметров, которые можно будет использовать внутри нашего A
:
modules.define(
'A',
['B', 'C'],
function(provide, b, c) {
}
);
С помощью метода provide(a)
разрешим, в свою очередь, другим модулям использовать наш:
modules.define(
'A',
['B', 'C'],
function(provide, b, c) {
provide(a);
}
);
И, наконец, поместим внутрь обёртки начинку – новый компонент var a = {}
:
modules.define(
'A',
['B', 'C'],
function(provide, b, c) {
var a = 'Candies are awesome';
provide(a);
}
);
Готово. Наш компонент помещён в удобный контейнер и доступен для взаимодействия с другими компонентами, расположенными в их собственных модулях.
Вот другой абстрактный пример – код модуля, отвечающего за форму логина:
modules.define(
'y-form',
['y-button'],
function(provide, button) {
//помещаем код компонента внутрь модуля:
var form = getElementById('my-form');
form.on('submit', onSubmited);
function onSubmited() {
if ($(button).css('disabled')) {
return false;
}
form.submit();
}
//конец кода компонента
provide(form);
}
);
Здесь, в теле анонимной функции, мы программируем поведение формы в зависимости от того, активна кнопка или нет. Используя метод define()
, мы определяем сам модуль с анонимной функцией внутри. Используя метод provide()
, мы заявляем, что данный модуль может быть вызван другими.
Модули независимы и запускаются лишь в случае, если все их зависимости зарезолвлены. Резолвятся они асинхронно, и дерево зависимостей строится в рантайме. Модули можно переопределять и доопределять в любой момент.
Дерево зависимостей модульной системы также можно и удобно использовать в любом файловом сборщике: имя модуля легко мапится на имя файла, в котором этот модуль хранится.