Яндекс карты. Получить данные объекта внутри кластера при клике
На карте вывожу много меток, которые объединяются в кластеры. Так же, есть форма, в поля которых должны попадать значения объекта, кликнутого на карте.
Так вот, если кликнуть по одиночному маркеру, то проблем нет, это я сделал, но проблема в том, что мне нужно чтобы поля формы заполнялись и при клике на объекте внутри любого кластера (когда кликаешь на кластер, там список из объектов) -
А я не пойму как получить клик по этим объектам и данные из них
Вот мой код карты
ymaps.ready(function () {
var myMap = new ymaps.Map('map', {
center: [56.841542, 60.571872],
zoom: 4,
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);
let cityId = objectManager.objects.getById(id).properties.cityId;
let shopId = objectManager.objects.getById(id).properties.shopId;
let shopText = objectManager.objects.getById(id).properties.shopName;
$('#contacts_form .js-cities-select').val(cityId).trigger('change');
initShopsSelect($('#contacts_form .js-shops-select'), shopId, shopText);
});
objectManager.clusters.events.add('balloonopen', function (e) {
// Получим id кластера, на котором открылся балун.
var id = e.get('objectId'),
// Получим геообъекты внутри кластера.
cluster = objectManager.clusters.getById(id),
geoObjects = cluster.properties.geoObjects;
console.log(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({
url: '/local/ajax/map_balloons_json.php',
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: "/local/ajax/map_data_json.php"
}).done(function (data) {
objectManager.add(data);
});
});
вот так выглядит массив объектов внутри кластера, когда кликнешь по нему
Ответы (2 шт):
Проще всего привязаться к clusterCaption. Обёртываешь его в span,
geoObject.properties.clusterCaption= '<span class="cluster-caption" data-id="' + geoObject.id + '">' + data[geoObject.id].clusterCaption+'</span>'
а затем вешаешь обработчик клика по этому span,
$('body').on('click','.cluster-caption', (e) => {
...
});
берёшь его id, - а дальше элементарно. И даже не нужно будет привязываться к событиям балуна.
Прикладываю пример получения значений объекта из кластера:
var monitor; var g; clusterer.events.group().add('balloonopen', e => { if (monitor) { monitor.removeAll(); monitor = undefined; }
var cluster = e.get('cluster');
console.log('activeObject', cluster.state.get('activeObject'))
monitor = new ymaps.Monitor(cluster.state)
.add('activeObject', () => {
console.log('activeObject', cluster.state.get('activeObject'))
});
})
В примере используются поля state и balloonopen.