Функция удаления маркера карт Google не вызывается в ReactJS - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь реализовать пользовательские маркеры на картах Google в моем приложении ReactJS. Теперь, когда я получил маркеры, я хотел бы иметь возможность удалить их. Это код для размещения и удаления маркеров. Однако, когда я нажимаю на кнопку удаления в информационном окне, кажется, ничего не происходит.

  addInfoWindow(marker, message, map) {
    var infoWindow = new google.maps.InfoWindow({
      content: message
    });

    google.maps.event.addListener(marker, "click", function() {
      infoWindow.open(map, marker);
    });
  }

  deleteMarker() {
    console.log('Delete');
  }

  placeMarker = (map, location) => {
    let marker = new google.maps.Marker({
      position: location,
      map: map,
      icon: red_flag
    });

    var contentString =
      '<button type="button" class="btn btn-danger" onClick="' +
      this.deleteMarker +
      '">Delete</button>';

    this.addInfoWindow(marker, contentString, map);
  };

Я также пытался с;

deleteMarker = () => {
    console.log('Delete');
}

Когда я нажимаю на кнопку, метод не вызывается и нет ошибок на консоли. Что может быть не так с этим кодом? Сгенерированный HTML код для этой строки содержимого:

<button type="button" class="btn btn-danger" onclick="function () {
      console.log('Delete');
    }">Delete</button>

Чтобы пояснить более подробно, я бы хотел, чтобы строка для кнопки удаления вела себя так;

<button type="button" class="btn btn-danger" onClick={() => this.deleteMarker("param")}>
    Delete
</button>

deleteMarker = param => {
    console.log("Delete", param);
};

1 Ответ

1 голос
/ 20 февраля 2020

Вы пытаетесь использовать код, как будто он будет выполняться с использованием JSX в React, но Google Maps и HTML не работают таким образом. Карты Google сами по себе не используют React, и поэтому библиотека Карт Google работает без каких-либо знаний о том, как работает React, и React работает независимо от того, как работают Карты Google. По этой причине каждый пакет React Google Maps должен работать с необработанным DOM или обернуть библиотеку Google Maps, чтобы предотвратить утечки памяти, ошибки или другие поломки. Когда вы создаете объект InfoWindow с контентом, этот контент создаст HTML независимо от React, что означает, что для того, чтобы он работал так, как вы этого хотите, вы должны работать со слушателями DOM самостоятельно.

Что вы Написал создаст функцию при нажатии на нее, но она не выполняется. Внутри атрибута onclick HTML он содержит выражение JavaScript, ограниченное глобально. Если это просто выражение функции, аналогичное тому, которое вы получите с любым из этих параметров, оно будет создавать функцию только как выражение, но не выполнять ее.

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

Я бы предложил создать уникальный идентификатор для кнопки, чтобы вы могли получить ее, как только она будет прилагается. Оттуда вам нужно будет получить ссылку на эту кнопку после ее добавления, а затем добавить к ней прослушиватель событий, который удалит маркер.

В вашем примере это может выглядеть так:

  addInfoWindow(marker, message, map, uniqueId) {
    var infoWindow = new google.maps.InfoWindow({
      content: message
    });

    google.maps.event.addListener(marker, "click", function() {
      infoWindow.open(map, marker);
    });

    google.maps.event.addListener(infoWindow, 'domready', () => {
        document.getElementById(uniqueId)
            .addEventListener('click', this.deleteMarker.bind(this));
    });
  }

  deleteMarker() {
    console.log('Delete');
  }

  placeMarker = (map, location) => {
    let marker = new google.maps.Marker({
      position: location,
      map: map,
      icon: red_flag
    });

    var uniqueId = 'delete-marker-'+ getAUniqueId();

    var contentString =
      '<button type="button" class="btn btn-danger" id="' + uniqueId + '">Delete</button>';

    this.addInfoWindow(marker, contentString, map, uniqueId);
  };

И это должно помочь вам.

Но поскольку вы имеете дело с необработанными элементами DOM, вы должны убедиться, что вы можете очистить этот прослушиватель событий при удалении маркера и информационного окна. Это потребует от вас также захвата той функции, которую вы создаете при привязке функции deleteMarker (хотя вам не нужно захватывать ее дополнительно, если вы используете функцию стрелки или привязываете метод к вашему экземпляру в конструкторе компонентов).

Некоторые заметные ссылки:

...