Клуб API Карт

Асинхронная перезагрузка карты при событии формы

yd-rbwest
3 декабря 2014, 14:04

Добрый день. Есть страница с формой, форма отправляет асинхронный запрос на сервер, сервер обрабатывает параметры и возвращает результат. Можно ли как то реализовать, что бы карта на этой странице асинхронно обновлялась с каждым новым ответом сервера? Заранее спасибо!

16 комментариев
Подписаться на комментарии к посту
Всеволод Шмыров
3 декабря 2014, 14:15
Добрый день. Это вопрос не к API, а к вашей архитектуре. Вам достаточно в слушателе получения данных (загрузки данных) производить манипуляции с картой.
То есть, в success: function(result) аякс-запроса как то это делать?
Всеволод Шмыров
3 декабря 2014, 15:29
А что вам нужно сделать с картой?
У меня карта стартует вместе со страницей, на которой представлены объекты ( с адресами, координатами и прочими параметрами), и есть фильтр поиска, работает на Jquery.Forms, при изменении параметром текстовый блок асинхронно обновляется, вот думаю как карту еще по событию submit так же обновлять))
Всеволод Шмыров
3 декабря 2014, 15:44
По идеи вам нужно в success просто удалять/добавлять геообъекты по полученным данным. Как я понимаю, вы при помощи формы меняете фильтр, посылаете новое значение фильтра серверу, а ответу хотите фильтр применить. А не правильней применять фильтр сразу и не дожидаться ответа от сервера? В этом случае не будет визуальной задержки.
Нет, я не хочу применить фильтр ответу. В зависимости от заданных в фильтре параметров я просто получаю разные ответы, то есть например пользователь забил адрес офиса - ул.Такаято, и ему пришел ответ что на этой улице 2 офиса.
А такая мысль - допустим, при старте страницы карта загружается с дефолтными параметрами, а при событии сабмит формы ее (карту) каждый раз инициализировать?
Всеволод Шмыров
3 декабря 2014, 16:33
Зачем пересоздавать карту? Не очень понимаю в чем сложность. В функции, которая вызывается по окончанию загрузки можно производить любую операцию с картой - вызывать любой метод и т.п.

Вот! Я это умом то понимаю, а как сделать? Вот так сделал, работает, но чувствую что это полный бред

$(function(){
$('#mapsform').submit(function(){

jQuery('.loading').show();
$('.info').html('');
$('#map').html(''); 

var m_method=$(this).attr('method');

var m_action=$(this).attr('action');

var m_data=$(this).serialize();
$.ajax({

     
success: function(){


ymaps.ready(function () {
    var myMap = window.map = new ymaps.Map('map', {
            center: [55.751574, 37.573856],
            zoom: 10,
            behaviors: ['default', 'scrollZoom']
        });
       
        /**
         * Создадим кластеризатор, вызвав функцию-конструктор.
        
         */
            clusterer = new ymaps.Clusterer({
           
            preset: 'twirl#invertedBluetClusterIcons',
           
            groupByCoordinates: false,
           
            clusterDisableClickZoom: true
        }),
       
       
        $.ajax({
       
        type: "GET",
        url:'mapsdata.php/?'+m_data,
        dataType: "json",
        success: function(data){
        var rows = data;
        for(var i in rows){
        var colls=rows[i];
        var info_res='';
            getPointData = function (index) {
            return {
                balloonContentHeader: ''+colls['balloonContentHeader']+'',
                balloonContentBody: '' + colls['address'] + '_' + colls['id'] +'',
                balloonContentFooter: colls['balloonContentFooter'],
                clusterCaption: colls['balloonContentHeader']
            };
        },
       
        info_res=info_res+'

  • '+''+colls['balloonContentHeader']+''+m_data+'
  • ';
             $('.info').append(info_res);  
                getPointOptions = function () {
               
                if(colls['typ'] === "0")
                return {
                    preset: 'twirl#greenIcon'
                };
               
                if(colls['typ'] === "2")
                return {
                    preset: 'twirl#redIcon'
                };
               
                else
                return {
                    preset: 'twirl#redIcon'
                };
            },
           
            points = [[colls['x'],colls['y']]],
            geoObjects = [];

       
        for(var i = 0, len = points.length; i < len; i++) {
            geoObjects[i] = new ymaps.Placemark(points[i], getPointData(i), getPointOptions());
           
        }

       
        clusterer.options.set({
            gridSize: 64,
            clusterDisableClickZoom: true
        });

       
        clusterer.add(geoObjects);

       
       

       
       

        myMap.geoObjects.add(clusterer);
       
       
         }
       
            }

        });   
       
       
       
    });







    jQuery('.loading').hide();


    }
    });
    return false;
    });


    });


    да не то слово))) два раза реди, два раза аякс....

    а вообще, в природе  есть варианты сделать по уму? Просто если есть, то буду пытаться, если это можно сделать только на костылях, то смысла нет.

    Варианты есть всегда.

    Надо использовать ООП и MVC, –

    работу с формами, получение данных, отрисовку их на карте нельзя валить в одну кучу.

    Понимаю, но сам видимо не скоро осилю... все что было в пределах моих знаний по JS я исчерпал))) но больше всего мне интересно - это все можно реализовать без перезагрузки карты, то есть что бы менялись только метки, а сама карта не перерисовывалась? При условии, конечно, что координаты центра не меняются

     

    Можно

    1. Удалить все из кластеризатора

    2. Добавить новые метки в кластеризатор

    Ага, вроде проясняется)) dimik, спасибо!

    Проясняется, но не очень... вот делаю так

     

    points = [[colls['x'],colls['y']]],
                      geoObjects = [];
                     
                      for(var i = 0, len = points.length; i < len; i++) {
                          geoObjects[i] = new ymaps.Placemark(points[i], getPointData(i));
           
                          }
                         
                          clusterer.options.set({
                          gridSize: 64,
                          clusterDisableClickZoom: true
                          });
                         
                         clusterer.removeAll();
                         
                         clusterer.add(geoObjects);
                         myMap.geoObjects.add(clusterer);

     

    в этом случае при событии сабмит появляется только одна метка с последним объектом из базы. Если удалить

    clusterer.removeAll();

    то все открывается правильно, но при повторном сабмите кол-во объектов в кластерах увеличивается.

    Подскажите, как в моем случае грамотно обновлять объекты в кластерах при событии сабмит? И еще вопрос - страница грузится с пустой картой, метки на карте появляются только при сабмите формы, как задать дефолтные параметры карте в моем случае

    (привожу полный код)

    ymaps.ready(function () {
        var myMap = window.map = new ymaps.Map('map', {
                center: [55.751574, 37.573856],
                zoom: 10,
                behaviors: ['default', 'scrollZoom']
            });
               
                   

                    clusterer = new ymaps.Clusterer({
               
                    preset: 'twirl#invertedBluetClusterIcons',
               
                    groupByCoordinates: false,
               
                    clusterDisableClickZoom: true
            }),
                   
                   
                   
                $('#smf').submit(function () {
                    var search_query = $('input[name=brest]').val();

                     $.ajax({
                     type: "GET",
                     url:'mapsdata.php?type='+search_query,
                     dataType: "json",
                     success: function(data){
                     var rows = data;
                     for(var i in rows){
                     var colls=rows[i];
                     getPointData = function (index) {
                    return {
                    balloonContentHeader: ''+colls['balloonContentHeader']+'',
                    balloonContentBody: '' + colls['address'] + '_' + colls['id'] +'',
                    balloonContentFooter: colls['balloonContentFooter'],
                    clusterCaption: colls['balloonContentHeader']
                };
                    },
                   
                      points = [[colls['x'],colls['y']]],
                      geoObjects = [];
                     
                      for(var i = 0, len = points.length; i < len; i++) {
                          geoObjects[i] = new ymaps.Placemark(points[i], getPointData(i));
           
                          }
                         
                          clusterer.options.set({
                          gridSize: 64,
                          clusterDisableClickZoom: true
                          });
                         
                         clusterer.removeAll();
                         
                         clusterer.add(geoObjects);
                         myMap.geoObjects.add(clusterer);
                    
                     
                        }
                     
                     }
                   
                    });
                    return false;
                });
               

    });

     

    Все, с очисткой кластеров разобрался

    clusterer.removeAll(); надо указывать ДО начала отрисовки

    Осталось только понять, как задать карте дефолтные значения при загрузке страницы.