react-leaflet 和 leaflet-editable:在活动期间创建额外的标记?
react-leaflet and leaflet-editable: create additional marker during event?
我正在尝试实现这样的功能,即在放置可编辑传单的标记时,按住控件并单击以放置标记,然后立即初始化要放置的另一个标记。结果是用户可以按住控制键快速将多个标记排成一行。
我试图通过响应 editable:drawing:commit
事件并在那里调用 map.editTools.createMarker
来实现此功能。但是,这样做似乎没有效果;放置标记后,用户离开编辑模式,必须手动开始放置另一个标记。
我也尝试回复 editable:drawing:end
,但这似乎有不一致的行为,有时它会按照描述的方式行事,有时它不会放置第二个标记。
Here is the CodeSandbox 我能够在其中重现一个最小示例。事件的处理方式是否存在错误,或者我只是捕获了错误的事件?
我花了一些时间玩这个,问题是 react 中 useState 调用的异步性质。当您这样做时:
"editable:drawing:commit": (event) => {
if (event.originalEvent.ctrlKey) {
setAdditionalMarker(true);
}
},
此状态更改不是即时的。放置单个标记时,drawing:end
事件似乎在 drawing:commit
事件之后立即发生。所以当你监听 end
事件时:
"editable:drawing:end": (event) => {
if (additionalMarker) {
addMarker();
setAdditionalMarker(false);
}
}
additionalMarker
还不是真的,因为 setAdditionalMarker(true)
还没有注册到 react,因为它是异步的。因此 if
语句永远不会被调用。
从用户体验的角度来看,这也有点没有意义,因为即使 useState 是同步的,如果用户在单击时按住 ctrl,但在单击之前释放了 ctrl 键再次映射,它将停留在编辑模式。但是在 keyup 上,它应该退出编辑模式。我的做法是将 keyup
和 keydown
听众附加到 文档 。在 keydown 上我们可以 setAdditionalMarker(true)
,而在 keyup 上则相反。如果 additionalMarkers
为真,我们会在点击事件后重新触发 addMarkers()
。但是,如果发生 keyup 事件,我们可以调用 map.editTools.commitDrawing()
强制退出编辑模式,页面光标恢复正常。
我们仍然有异步useState问题,因为在keyup上,我们将additionalMarkers
设置为false,同时触发editable:drawing:end
事件时间,但 setAdditionalMarkers
是异步的,所以 additionalMarkers
仍然为真,我们陷入了可编辑模式。为了解决这个问题,我将 map.editTools.commitDrawing()
包装在 50 毫秒的超时中,以便它发生在 之后 异步 useState 调用完成。它有点 hacky,但它可以工作并且对 UX 有好处。可能有更合适的方法来做到这一点。
Working codesandbox
**注意:我在 mac 上,所以我将左侧命令键的键更改为 lsiten...您可能需要调整 keydown 和 keyup 事件中的键码 windows 或为了跨平台兼容性。
我正在尝试实现这样的功能,即在放置可编辑传单的标记时,按住控件并单击以放置标记,然后立即初始化要放置的另一个标记。结果是用户可以按住控制键快速将多个标记排成一行。
我试图通过响应 editable:drawing:commit
事件并在那里调用 map.editTools.createMarker
来实现此功能。但是,这样做似乎没有效果;放置标记后,用户离开编辑模式,必须手动开始放置另一个标记。
我也尝试回复 editable:drawing:end
,但这似乎有不一致的行为,有时它会按照描述的方式行事,有时它不会放置第二个标记。
Here is the CodeSandbox 我能够在其中重现一个最小示例。事件的处理方式是否存在错误,或者我只是捕获了错误的事件?
我花了一些时间玩这个,问题是 react 中 useState 调用的异步性质。当您这样做时:
"editable:drawing:commit": (event) => {
if (event.originalEvent.ctrlKey) {
setAdditionalMarker(true);
}
},
此状态更改不是即时的。放置单个标记时,drawing:end
事件似乎在 drawing:commit
事件之后立即发生。所以当你监听 end
事件时:
"editable:drawing:end": (event) => {
if (additionalMarker) {
addMarker();
setAdditionalMarker(false);
}
}
additionalMarker
还不是真的,因为 setAdditionalMarker(true)
还没有注册到 react,因为它是异步的。因此 if
语句永远不会被调用。
从用户体验的角度来看,这也有点没有意义,因为即使 useState 是同步的,如果用户在单击时按住 ctrl,但在单击之前释放了 ctrl 键再次映射,它将停留在编辑模式。但是在 keyup 上,它应该退出编辑模式。我的做法是将 keyup
和 keydown
听众附加到 文档 。在 keydown 上我们可以 setAdditionalMarker(true)
,而在 keyup 上则相反。如果 additionalMarkers
为真,我们会在点击事件后重新触发 addMarkers()
。但是,如果发生 keyup 事件,我们可以调用 map.editTools.commitDrawing()
强制退出编辑模式,页面光标恢复正常。
我们仍然有异步useState问题,因为在keyup上,我们将additionalMarkers
设置为false,同时触发editable:drawing:end
事件时间,但 setAdditionalMarkers
是异步的,所以 additionalMarkers
仍然为真,我们陷入了可编辑模式。为了解决这个问题,我将 map.editTools.commitDrawing()
包装在 50 毫秒的超时中,以便它发生在 之后 异步 useState 调用完成。它有点 hacky,但它可以工作并且对 UX 有好处。可能有更合适的方法来做到这一点。
Working codesandbox
**注意:我在 mac 上,所以我将左侧命令键的键更改为 lsiten...您可能需要调整 keydown 和 keyup 事件中的键码 windows 或为了跨平台兼容性。