javascript - 谷歌地图标记删除功能未在 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);
};
解决方案
您正在尝试使用代码,就好像它要在 React 中使用 JSX 一样执行,但 Google Maps 和 HTML 不能那样工作。Google Maps 本身不使用 React,因此,Google Maps 库在不了解 React 如何工作的情况下工作,并且 React 独立于 Google Maps 如何工作。因此,每个 React Google Maps 包都必须使用原始 DOM 或包装 Google Maps 库,以防止内存泄漏、错误或其他损坏。当您创建一个带有内容的 InfoWindow 对象时,该内容将创建独立于 React 的 HTML,这意味着要使其按您希望的方式工作,您必须自己使用 DOM 侦听器。
您编写的内容将在单击它时创建一个函数,但它不会执行。在onclick
HTML 的属性内部,它包含一个全局作用域的 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
函数(尽管如果您使用箭头函数或将方法绑定到组件构造函数中的实例,则不必额外捕获它)。
一些值得注意的参考资料:
- 谷歌地图事件文档 - https://developers.google.com/maps/documentation/javascript/reference/event
- 信息窗口文档;
domready
事件 - https://developers.google.com/maps/documentation/javascript/reference/info-window#InfoWindow.domready - MDN HTML
onclick
属性(注意它是“过时的”,因为有更好的注册事件处理程序的方法,尽管对于该特定文章它也可能是“过时的”,也许有更新的) - https://developer.mozilla.org /en-US/docs/Archive/Mozilla/XUL/Attribute/onclick - W3 学校
onclick
属性指南 - https://www.w3schools.com/TAgs/att_onclick.asp
推荐阅读
- c# - “shutdown.exe”破坏应用程序设置
- linux - 壳牌一班轮别名howto?
- python - 使用 Pyinstaller 创建的二进制文件失败:“No module named ...”、“Failed to execute script ...”使用 Pipenv 时
- html - 是否可以将 Bootstrap 集成到 App Maker 中?
- sql - 选择 Max() 太慢了
- sql - MS Access 在数据表中显示 vba 选择查询
- javascript - AngularJS:从父母那里获取孩子的状态名称
- python - PyTorch RuntimeError 大小的参数 2 无效
- ansible - Ansible - Centos 机器,ansible_lsb 为空
- sql - 未知列数的 SQL Server 动态数据透视