首页 > 解决方案 > 谷歌地图标记删除功能未在 ReactJS 中调用

问题描述

我正在尝试在我的 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);
};

标签: javascriptreactjsmapsmarker

解决方案


您正在尝试使用代码,就好像它要在 React 中使用 JSX 一样执行,但 Google Maps 和 HTML 不能那样工作。Google Maps 本身不使用 React,因此,Google Maps 库在不了解 React 如何工作的情况下工作,并且 React 独立于 Google Maps 如何工作。因此,每个 React Google Maps 包都必须使用原始 DOM 或包装 Google Maps 库,以防止内存泄漏、错误或其他损坏。当您创建一个带有内容的 InfoWindow 对象时,该内容将创建独立于 React 的 HTML,这意味着要使其按您希望的方式工作,您必须自己使用 DOM 侦听器。

您编写的内容将在单击它时创建一个函数,但它不会执行。在onclickHTML 的属性内部,它包含一个全局作用域的 JavaScript 表达式。如果它只是一个函数表达式,就像您将使用这些选项中的任何一个获得的一样,它只会将函数创建为表达式,但不会执行它。

相反,您将不得不使用全局函数来删除标记(绝不可取)或手动添加事件侦听器(hacky,但可能是必要的)。

我建议为按钮创建一个唯一的 ID,以便在添加后获取它。从那里,您必须在附加该按钮后获取对该按钮的引用,然后向其添加一个事件侦听器以删除标记。

使用您的示例,它可能如下所示:

  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函数(尽管如果您使用箭头函数或将方法绑定到组件构造函数中的实例,则不必额外捕获它)。

一些值得注意的参考资料:


推荐阅读