---
metadata:
  - name: generator
    content: Diplodoc Platform v5.39.1
alternate:
  - https://yandex.com.tr/dev/jsapi-v2-1/doc/ru/v2-1/examples/cases/om_balloon_ajax.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.com.tr/dev/jsapi-v2-1/doc/ru/llms.txt

# Динамическая загрузка содержимого балуна

<iframe id="LIVE-EXAMPLE" style="width:100%;height: 400px;border-radius: 8px;border: 1px solid rgba(92, 94, 102, 0.14);" frameBorder="0" src="https://yastatic.net/s3/front-maps-static/maps-front-jsapi-v2-1/examples/2/out/s3-cases/ru/om_balloon_ajax/index.html" allow="fullscreen"></iframe>

<a target="_blank" rel="noopener noreferrer" style="display: inline-block;margin-top: 10px;cursor: pointer;border-radius: 4px;padding: 9px 12px;background: #151515;color: white;text-decoration: none;font-weight: 500" href="https://codesandbox.io/p/sandbox/mm3hmx?file=index.html">Open in CodeSandbox</a>

<div id="references">
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/ready">ready</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/Map">Map</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/ObjectManager">ObjectManager</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/objectManager.Balloon">objectManager.Balloon</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/Event">Event</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/geoQuery">geoQuery</a>
</div>
<p>
    Часто при работе с картой приходится загружать большой объем дополнительных данных (текстовая информация, картинки и пр.).
    При этом загруженная информация не всегда используется пользователем. Например, когда на карте
    отображены сотни меток, и балун каждой из них содержит большой объем текста. При работе с картой пользователь может
    не открыть ни один балун, но данные все равно будут загружены.
</p>
<p>
    В таких случаях в целях экономии трафика имеет смысл загружать данные не сразу, а по мере необходимости.
</p>
<p>
    Данный пример демонстрирует динамическую загрузку содержимого балуна с помощью AJAX-запроса.
</p>
<p>
    При клике на значок кластера или одиночной метки производится проверка, загружено ли
    содержимое их балуна. Если для каких-либо меток текст балуна не задан, серверу отправляется POST-запрос
    с массивом идентификаторов этих меток. Сервер обрабатывает массив и на его основе
    возвращает JSON-объект, содержащий необходимые данные.
</p>
<p>
    Обратите внимание, что серверную часть необходимо реализовать самостоятельно.
</p>

{% list tabs %}

-   index.html

    ```html
    <!DOCTYPE html>

    <html>
        <head>
            <title>Динамическая загрузка содержимого балуна</title>
            <meta
                http-equiv="Content-Type"
                content="text/html; charset=utf-8"
            />
            <!--
            Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
            Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
        -->
            
            
            
            
        </head>

        <body>
            <div id="map"></div>
        </body>
    </html>
    ```

-   om_balloon_ajax.js

    ```js
    ymaps.ready(function () {
        var myMap = new ymaps.Map("map", {
                center: [55.751574, 37.573856],
                zoom: 10,
                controls: [],
            }),
            objectManager = new ymaps.ObjectManager({
                clusterize: true,
                clusterDisableClickZoom: true,
            });
        myMap.geoObjects.add(objectManager);

        objectManager.objects.events.add("balloonopen", function (e) {
            // Получим объект, на котором открылся балун.
            var id = e.get("objectId"),
                geoObject = objectManager.objects.getById(id);
            // Загрузим данные для объекта при необходимости.
            downloadContent([geoObject], id);
        });

        objectManager.clusters.events.add("balloonopen", function (e) {
            // Получим id кластера, на котором открылся балун.
            var id = e.get("objectId"),
                // Получим геообъекты внутри кластера.
                cluster = objectManager.clusters.getById(id),
                geoObjects = cluster.properties.geoObjects;

            // Загрузим данные для объектов при необходимости.
            downloadContent(geoObjects, id, true);
        });

        function downloadContent(geoObjects, id, isCluster) {
            // Создадим массив меток, для которых данные ещё не загружены.
            var array = geoObjects.filter(function (geoObject) {
                    return (
                        geoObject.properties.balloonContent ===
                            "идет загрузка..." ||
                        geoObject.properties.balloonContent === "Not found"
                    );
                }),
                // Формируем массив идентификаторов, который будет передан серверу.
                ids = array.map(function (geoObject) {
                    return geoObject.id;
                });
            if (ids.length) {
                // Запрос к серверу.
                // Сервер обработает массив идентификаторов и на его основе
                // вернет JSON-объект, содержащий текст балуна для
                // заданных меток.
                ymaps.vow
                    .resolve(
                        $.ajax({
                            // Обратите внимание, что серверную часть необходимо реализовать самостоятельно.
                            //contentType: 'application/json',
                            //type: 'POST',
                            //data: JSON.stringify(ids),
                            url: "content.json",
                            dataType: "json",
                            processData: false,
                        })
                    )
                    .then(function (data) {
                        // Имитируем задержку от сервера.
                        return ymaps.vow.delay(data, 1000);
                    })
                    .then(
                        function (data) {
                            geoObjects.forEach(function (geoObject) {
                                // Содержимое балуна берем из данных, полученных от сервера.
                                // Сервер возвращает массив объектов вида:
                                // [ {"balloonContent": "Содержимое балуна"}, ...]
                                geoObject.properties.balloonContent =
                                    data[geoObject.id].balloonContent;
                            });
                            // Оповещаем балун, что нужно применить новые данные.
                            setNewData();
                        },
                        function () {
                            geoObjects.forEach(function (geoObject) {
                                geoObject.properties.balloonContent =
                                    "Not found";
                            });
                            // Оповещаем балун, что нужно применить новые данные.
                            setNewData();
                        }
                    );
            }

            function setNewData() {
                if (isCluster && objectManager.clusters.balloon.isOpen(id)) {
                    objectManager.clusters.balloon.setData(
                        objectManager.clusters.balloon.getData()
                    );
                } else if (objectManager.objects.balloon.isOpen(id)) {
                    objectManager.objects.balloon.setData(
                        objectManager.objects.balloon.getData()
                    );
                }
            }
        }

        $.ajax({
            url: "data.json",
        }).done(function (data) {
            objectManager.add(data);
        });
    });
    ```

{% endlist %}
