Leaflet Draw重复触发draw:created事件导致绘图对象重复提交问题求助
解决Leaflet Draw重复触发
draw:created事件导致数据重复提交的问题 我来帮你分析下这个问题,核心原因是事件监听器被重复绑定了,咱们一步步拆解解决:
问题根源
每次你执行new this.$leaflet.Draw.Marker(this.map.object)并启用后,又给地图对象绑定了一次draw:created事件。第二次创建标记/多边形时,地图上已经累积了多个相同的事件监听器,所以每次完成绘制都会触发所有监听器,导致打印多个事件对象、重复提交数据。
另外你遇到的两个错误也能对应上:
- 调用
removeHooks()报错:这是Leaflet Draw内部的私有钩子方法,不是给外部调用的,直接调用会因为内部_tooltip已被销毁而抛出空指针错误; map.removeControl(draw)报错:因为你创建的是L.Draw.Marker绘制实例,而非L.Control.Draw控件,removeControl只对地图控件生效,所以无法识别这个Draw实例。
解决方案
方案1:只绑定一次draw:created事件(推荐)
把事件监听逻辑放到地图初始化阶段,而不是每次创建Draw实例时重复绑定。这样不管创建多少次绘制工具,事件只会触发一次:
// 在地图初始化的代码中,只绑定一次draw:created事件 this.map.object.on('draw:created', (event) => { event.layer.addTo(this.map.object) this.doCreateAnnotation(event) }) // 创建标记点的函数只负责实例化并启用绘制工具 createMarker() { const draw = new this.$leaflet.Draw.Marker(this.map.object) draw.enable() } // 创建多边形的函数同理 createPolygon() { const draw = new this.$leaflet.Draw.Polygon(this.map.object) draw.enable() }
方案2:每次绑定前移除旧的监听器
如果业务逻辑需要动态绑定/解绑,可以把事件处理函数抽成命名函数,每次创建Draw实例前先移除旧的监听器:
// 抽成命名函数,方便后续移除监听 handleDrawCreated = (event) => { event.layer.addTo(this.map.object) this.doCreateAnnotation(event) } createMarker() { // 先移除之前的draw:created监听器 this.map.object.off('draw:created', this.handleDrawCreated) // 绑定新的监听器 this.map.object.on('draw:created', this.handleDrawCreated) const draw = new this.$leaflet.Draw.Marker(this.map.object) draw.enable() }
额外优化:绘制完成后禁用工具
如果需要在绘制完成后自动关闭当前绘制工具,可以在事件处理函数里添加禁用逻辑:
this.map.object.on('draw:created', (event) => { event.layer.addTo(this.map.object) this.doCreateAnnotation(event) // 禁用当前绘制工具 this.$leaflet.Draw._getInstance(this.map.object).disable() })
内容的提问来源于stack exchange,提问作者adamlmiller
相关产品推荐
相关产品推荐

