innabelaya / ymapsbem

Статья об использовании АПИ Яндекс.Карт совместно с методологией БЭМ (www.bem.info).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

API Яндекс.Карт и БЭМ

Один из самых частых кейсов использования API Яндекс.Карт — создание меню для показа на карте организаций различных типов (коллекций геообъектов). С помощью такого меню пользователь сайта может отобразить на карте только те объекты, которые его интересуют. Например, вот так. Но давайте реализуем этот пример с помощью методологии БЭМ!

Первые шаги

Создатели БЭМ позаботились о разработчиках и создали проект-скелет, который поможет начать разработку «с низкого старта». Начнем с него.

git clone https://github.com/bem/project-stub.git shopsList
cd shopsList
npm install

Теперь проект у нас на компьютере. Давайте протестируем, все ли работает. Для этого нужно перейти в папку, запустить enb server и открыть в браузере страницу: localhost:8080/desktop.bundles/index/index.html Перед глазами должно быть что-то вроде:

Скомпилированная страница BEM project stub

Готово, можно переходить к следующему этапу.

Общее видение проекта

Нам нужно создать блок «map», в котором будет находиться карта, блок «sidebar» — правая или левая колонка, в которой будет находиться блок «menu», реализующий список организаций по категориям. Методология БЭМ подсказывает, что мы должны проектировать так, чтобы блоки не знали о существовании друг друга, поэтому нужно будет создать промежуточный блок, который будет принимать клики на меню и взаимодействовать с картой. Назовем его «i-geo-controller».

Чтобы лучше понять зачем нужен промежуточный блок, как он работает и что такое «миксы», рекомендуем посмотреть рассказ Кира Белевича «Миксы во вселенной БЭМ».

Описание страницы, написание bemjson

Здесь всё просто. Мы изначально продумали структуру страницы, основные блоки и теперь осталось все это записать в json-подобном виде. Не буду вдаваться в подробности, вы всегда можете посмотреть исходный код. Структура страницы будет такой:

    page
    == container
    ==== map
    ==== sidebar
    ====== menu
    ======== items

Структура страницы

В bemjson:

{
    block: 'page',
    content: [
        {
            block: 'container',
            content: [
                {
                    block: 'map'
                },
                {
                    block: 'sidebar',
                    content: [
                        {
                            block: 'menu',
                            content [ /* menu items */ ]
                        }
                    ]
                }
            ]
        }
    ]
}

Более подробно можно посмотреть здесь: desktop.bundles/index/index.bemjson.js

Блок map

Давайте начнем разработку с главного блока — карты. Прежде всего нужно подключить API с необходимыми опциями. Можно было бы создать отдельный блок i-API, но, кажется, куда удобнее реализовать все это в рамках одного блока, используя модификаторы. Для блока map мы создадим модификатор «api», в котором для начала разместим значение — «ymaps». В примере мы будем использовать динамический API, но нужно помнить, что мы можем использовать и static API. Это можно реализовать в рамках модификаторов.

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

{
    coords: [], // координаты метки
    properties: {}, // данные метки
    options: {}, // опции метки
}

Для коллекции:

{
    collection: true, // флаг, указывающий, что это коллекция / группа меток
    properties: {}, // свойства группы
    options: {}, // опции группы
    data: [], // массив меток.
}

Это покрывает 90% всех кейсов.

Блок menu

Здесь нам нужно сделать двухуровневое меню. Создаем блок menu, который будет распознавать клики по группам и элементам. Соответственно, нам нужны такие элементы:

  • item — элемент меню;
  • content — контейнер для элементов;
  • title — заголовок группы.

Вкладывая один блок меню в другой, можно добиться необходимой иерархичности.

Например, простейшее меню, описанное в bemjson будет выглядеть так:

{
    block: 'menu',
    content: [
        {
            elem: 'title',
            content: 'menu title'
        },
        {
            elem: 'content',
            content: [
                {
                    elem: 'item',
                    content: 'menu-item-1'
                },
                {
                    elem: 'item',
                    content: 'menu-item-2'
                }
            ]
        }
    ]
}

Блок i-geo-controller

Блок-контроллер, который подписывается на события блоков menu — «menuItemClick» и «menuGroupClick», реагирует на них и совершает определенные действия на карте. В нашем примере у него следующие задачи:

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

Кроме того, чтобы правильно взаимодействовать с картой, блок-контроллер должен знать, готова ли карта к тому, чтобы объектами на ней можно было управлять. Для этого блок map у себя будет пробрасывать событие «map-inited», а i-geo-controller — слушать его и запоминать ссылку на экземпляр карты.

Схема взаимодействия блоков

Заключение

Готовый пример можно посмотреть по ссылке: http://zloylos.github.io/ymapsbem/.

Возможно, с использованием методологии БЭМ пример и получился более громоздким, чем без неё, но зато у нас есть более структурированный и удобный для поддержки код. А главное, его довольно просто масштабировать и расширять, что без использования методологии вызвало бы значительные проблемы и чаще всего привело бы к полному переписыванию кода.

Готовый пример

Спасибо Саше Тармолову за ценные советы и помощь.

Фотография Денис Хананеин
Денис Хананеин,
Разработчик интерфейсов API Яндекс.Карт

About

Статья об использовании АПИ Яндекс.Карт совместно с методологией БЭМ (www.bem.info).


Languages

Language:JavaScript 96.9%Language:CSS 3.1%