Клуб API Карт

Каким способом можно удалить маркер после клика по нему?

Пост в архиве.

Подскажите пожалуйста какой способ использовать для удаления маркера после клика по нему? Вот мой минимальный пример кода. Здесь после клика по карте созаётся маркер, выводится на карту и его координаты сохраняются в localStorage.

js:

ymaps.ready(init);

var myMap,
    collectionMarkers,
    myPlacemark;

function init(){     
    myMap = new ymaps.Map("map", {
        center: [55.76, 37.64],
        zoom: 7
    });

    collectionMarkers = new ymaps.GeoObjectCollection({}, {
        preset: "islands#redIcon"
    });

    myMap.geoObjects.add(collectionMarkers);

    renderSavedPoints();

    myMap.events.add('click', function (e) {
        var coords = e.get('coords');
        console.log('lat:', coords[0], 'lng:', coords[1]);

        var placemark = new ymaps.Placemark([coords[0], coords[1]]); 
        addRightClickEvent(placemark);   
        collectionMarkers.add(placemark);  

        addToStoragePoint({
            lat: coords[0],
            lng: coords[1]
        });       
    });
};

function getPoints() {
    return localStorage.points ? JSON.parse(localStorage.points) : [];
};

function addToStoragePoint(pointObj) {
    console.log('addToStoragePoint start');
    var points = getPoints();
    points.push(pointObj);
    localStorage.points = JSON.stringify(points);
};

function renderSavedPoints() {
    console.log('renderSavedPoints start', collectionMarkers);
    var points = getPoints();

    points.forEach((point) => {        
        // console.log('lat:', point.lat, 'lng:', point.lng);
        var placemark = new ymaps.Placemark([point.lat, point.lng]);    
        addRightClickEvent(placemark);     
        collectionMarkers.add(placemark);
    });
};

function addRightClickEvent(placemark) {
    placemark.events.add('contextmenu', function (e) {
        var pointLat = e.get('coords')[0],
            pointLng = e.get('coords')[1];

        console.log('right click', e.get('coords'), pointLat, pointLng);        
        var points = getPoints(),
            newPoints = [];

        points.forEach((point) => {        
            console.log('lat:', point.lat, 'lng:', point.lng);
            if(point.lat != pointLat && point.lng != pointLng ) {
                console.log('add!!');
                newPoints.push(point);
            } else {
                console.log('del!!');
            }
        }); 

        localStorage.points = JSON.stringify(newPoints);     


    });     
};

JSFIDDLE

Проблема в том, что после клика правой кнопкой мыши по маркеру не происходит удаление из localStorage объекта с координатами маркера. И соответственно карта не перерисовывается на основе нового localStorage/

6 комментариев
В случае с localStorage нужно все же использовать интерфейс
Я не проверял, но подозреваю, что добавление поля points ничего в localStorage не сохраняет
dimik,
Почему не сохраняет? Сохраняет. Нажмите f12 в браузере и увидите это.
у вас адовая логика с этими forEach
1. Не надо навешивать слушателя на каждый плейсмарк
используйте делегирование событий


collectionMarkers.events.add('contextmenu', function(e) {
  // Метка по которой был правый клик будет лежать в 'target'
   console.log(e.get('target'));
});


2. Не надо строить логику на сравнении координат. Используйте какой-то свой properties.id или индекс, лучше вместо foreach брать идентификатор из данных метки


Вы меняете объект в localStorage.points, но я не вижу, где вы удаляете метку с карты
Обновлено 5 ноября 2017, 11:50
dimik,
Использовать делегирование это хорошая идея. Вот я переписал код с учётом этого. Но главную проблему удаления маркера после правого клика по нему я так и не придумал как решить.

Я понимаю, что лучше для хранения в локалсторадже использовать не координаты, и какой-нибудь id. Но как после клика определить, что я нажал по маркеру, который связан с определённым id, этого я не понимаю.

>>> Вы меняете объект в localStorage.points, но я не вижу, где вы удаляете метку с карты 
Я пока не реализовал удаление маркера с карты. Но это простая задача. Мне главное удалить данные маркера из локалстраджа. А это невозможно потому что очень маленькая вероятность того, что кликнув по маркеру, я попаду именно в те же координаты, что были при установке маркера(то есть маркер по площади довольно большой).
Sergey Kalinin,
    
Добавьте свои id:


points.forEach((point, index) => {
// console.log('lat:', point.lat, 'lng:', point.lng);
var placemark = new ymaps.Placemark([point.lat, point.lng], {id: 'id' + index});
addRightClickEvent(placemark);
collectionMarkers.add(placemark);
});


...


collectionMarkers.events.add('contextmenu', function(e) {
// Метка по которой был правый клик будет лежать в 'target'
console.log(e.get('target').properties.get('id'));
});


В локалсторадж лучше хранить не массив, а хэш


JSON.stringify({'id1': {lat: '...', lng: '...', id: ''} })

dimik,
Спасибо, всё получилось. Вот решение вашим способом, вот решение моим способом.