Клуб API Карт

Перерисовка карт, если они загружены

web@biosvyaz.com
17 января, 13:01

Всем приве)

Есть у меня поиск по клиентам, я вывожу информацию в двух видах - списком и на карте (метки с адресами). Поиск работает на аяксе. Нажимаю кнопку поиска, формируется запрос, выводятся данные из бд, плюс на карте строится много точек по адресам всех клиентов. 

API я подгружаю отложено, карту гружу только после выполнения аякса (рассматриваю еще вариант грузить тоже отложено, после перехода на нужную вкладку) в функции complete, предварительно проверяя подгрузилось ли api. Если api уже загружено, то инициализируем только карту, если нет, то сначала api потом инициализируем карту. 

Это при первом нажатии на кнопку поиска.

При повторном нажатии на кнопку поиска, мне нужно заново перерисовывать карту (api подгружен). Как это можно сделать? Если я просто создаю новую карту, то у меня с ней повторно загружается скрипт:

<script charset="utf-8" src="https://api-maps.yandex.ru/services/coverage/v2/?l=map&amp;ll=30.31586800,59.93909500&amp;z=5&amp;lang=ru_RU&amp;callback=jsonp_yandex_coverage__l_map_ll_30_31586800_59_93909500_z_5_lang_ru_RU&amp;sign=3567374399"></script>

Я так полагаю это скрипт инициализации. При его повторной загрузке, в консоль начинают циклически сыпаться сотни ошибок такого типа:

combine.js?load=6O6S@$(!(U(X!D(*()(,066U(@(j6V6X63(q(z(Q606165(I5z(Z67696a)d6$6_6!6*6:6;)h)k)m)o6q@…:273 Uncaught TypeError: Cannot read property 'offsetWidth' of null
    at Object.getSize (https://api-maps.yandex.ru/2.1.47/combine.js?load=6O6S@$(!(U(X!D(*()(,066U(…,C,D,FiGiFqR,H,L8v,MqSqTqUqVqXqYq08x&callback_prefix=ymaps_loader:273:4353)
    at v.fitToViewport (https://api-maps.yandex.ru/2.1.47/combine.js?load=2h2v0e9_0l@N1_,J9!1,1*1;,…@X*8*$*-6B*R@S@T6D*S@U*76E6G*.*!6K6M&callback_prefix=ymaps_loader:417:2446)
    at v._checkAutoFit (https://api-maps.yandex.ru/2.1.47/combine.js?load=2h2v0e9_0l@N1_,J9!1,1*1;,…@X*8*$*-6B*R@S@T6D*S@U*76E6G*.*!6K6M&callback_prefix=ymaps_loader:417:6218)
    at v.<anonymous> (https://api-maps.yandex.ru/2.1.47/combine.js?load=2h2v0e9_0l@N1_,J9!1,1*1;,…@X*8*$*-6B*R@S@T6D*S@U*76E6G*.*!6K6M&callback_prefix=ymaps_loader:417:5824)

Они сыплятся с частотой по 5-10 в секунду. Мне кажется такими частыми обращениями к серверу яндекса (если это так), его вообще положить можно, ддос какой-то D

В общем мне нужно при отправке ajax запроса, без повторных загрузок api обновлять карту, как это можно сделать?

2 комментария
Подписаться на комментарии к посту
web@biosvyaz.com
17 января, 13:38
По сути нужно проверять типа 
if (ymaps.ready()) {
myMap.redraw();
}


Но тут проблема в том, что myMap существует только в функции inint, а проверять и делать перерисовку нужно в ajax запросе поиска. Типа, если карта уже есть, то перерисовываем, если еще нет, то грузим api и создаем.
web@biosvyaz.com
18 января, 11:16
Не знание js) Просто глобальную переменную делаем. Плюс redraw в api 2.0 не работает, как пишут,  поэтому - myMap.content.fitToViewport() - вешаем на действие или событие. Хотя в моем случае (я добивался отложенной загрузки api - не во время поиска, а только при переходе на вкладку карты (показать на карте) плюс отсутствие повторной загрузки api при повторном поиске, так как поиск идет через ajax и api накапливается с каждым запросом поиска) немного не тривиально вышло. 


Код выложу тут (к сожалению тут вроде нет спойлеров для кода в комментариях):


var myMap;
/**
* Функция инициализации карты
*/
function init () {
myMap = new ymaps.Map('custom-search-map', {
center: [],
zoom: 8
}, {
searchControlProvider: 'yandex#search'
});
var objectManager = new ymaps.ObjectManager({
// Чтобы метки начали кластеризоваться, выставляем опцию.
clusterize: true,
// ObjectManager принимает те же опции, что и кластеризатор.
gridSize: 32
});
// Чтобы задать опции одиночным объектам и кластерам,
// обратимся к дочерним коллекциям ObjectManager.
objectManager.objects.options.set('preset', 'islands#greenDotIcon');
objectManager.clusters.options.set('preset', 'islands#greenClusterIcons');
myMap.geoObjects.add(objectManager);
var jsonFilePath = $('#custom-search-map').attr('data-json-path');
$.ajax({
url: jsonFilePath
}).done(function(response) {
var center = response.features[0].geometry.coordinates;
myMap.setCenter(center);
objectManager.add(response);
});
}
/**
* Функция загрузки API Яндекс.Карт по требованию (в нашем случае при выполнении ajax запроса)
*
* @param url
* @param callback
*/
function loadScript(url, callback){
var script = document.createElement("script");
if (script.readyState){ // IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { // Другие браузеры
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
/**
* Выводит результат поиска
*/
$('#custom-search-form').submit(function (e) {
e.preventDefault();
var formData = $(this).serialize();
$.ajax({
data : formData,
url : '/',
method : 'post',
dataType : 'html',
success : function (data) {
var searchResultHtml = $(data).find('.container-custom-search-result .list-view');
$('.container-custom-search-result #custom-search-result-pjax').html(searchResultHtml);
$('.container-custom-search-result').css('display', 'block');
/* Если открыт таб с картйо и api не инициализировано, то инициализируем и загружаем карту.
* Иначе просто загружаем карты, без инициализации api
* */
if (!$('script[src="http://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;loadByRequire=1"]').length) {
// Включение дебага &mode=debug
loadScript("http://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;loadByRequire=1", function(){
if ($('.container-custom-search-result #panel2').hasClass('active')) {
$('#custom-search-map').empty();
ymaps.load(init);
}
});
} else {
if ($('.container-custom-search-result #panel2').hasClass('active')) {
$('#custom-search-map').empty();
ymaps.load(init);
}
}
},
});
});
// Инициализируем карты при переходе на таб с картой.
$('.container-custom-search-result a[href="#panel2"]').on('show.bs.tab', function (e) {
ymaps.load(init);
});
// Очищаем контейнер с картой при переходе к списку результатов поиска
$('.container-custom-search-result a[href="#panel1"]').on('show.bs.tab', function (e) {
$('#custom-search-map').empty();
});