Odoo16重写MapRenderer类createMarkerPopup函数添加短信按钮失败求助
地图标记弹窗Send SMS按钮点击事件失效问题
我尝试在地图标记的弹窗里添加一个新的Send SMS按钮,但无法给这个按钮绑定点击事件,试了下面的代码没效果,求建议或示例。
(图:地图标记弹窗右下角显示Send SMS按钮)
我尝试的代码
import { MapRenderer } from "@web_map/map_view/map_renderer"; export class SmsMapRenderer extends MapRenderer { setup() { super.setup(); } createMarkerPopup(markerInfo, latLongOffset = 0) { const popup = super.createMarkerPopup(...arguments); debugger; // const popup = super.createMarkerPopup(markerInfo, latLongOffset); const popupFields = popup.getMarkerPopupFields(markerInfo); const partner = markerInfo.record.partner; const popupHtml1 = renderToString("renewell.sendsmsPopup", { fields: popupFields, hasFormView: this.props.model.metaData.hasFormView, }); const opensmsBtn = popup .getElement() .querySelector("button.o-map-renderer--popup-buttons-send_sms"); const offset = markerInfo.pinInSamePlace * 0.000050; if (opensmsBtn) { opensmsBtn.onclick = () => { const popup = L.popup({ offset: [0, -30] }) .setLatLng([ partner.partner_latitude + latLongOffset, partner.partner_longitude - latLongOffset, ]) .setContent(popupHtml1) .openOn(this.leafletMap); }; } return popup; } }
问题原因及解决方案
核心问题
调用父类方法后立即获取DOM元素,此时弹窗的DOM可能还未完全渲染完成,导致找不到按钮;或者后续父类逻辑重新渲染弹窗,清除了你的事件绑定。
修改后的代码示例
import { MapRenderer } from "@web_map/map_view/map_renderer"; export class SmsMapRenderer extends MapRenderer { setup() { super.setup(); } createMarkerPopup(markerInfo, latLongOffset = 0) { const popup = super.createMarkerPopup(...arguments); const partner = markerInfo.record.partner; const popupFields = popup.getMarkerPopupFields(markerInfo); const popupHtml1 = renderToString("renewell.sendsmsPopup", { fields: popupFields, hasFormView: this.props.model.metaData.hasFormView, }); const offset = markerInfo.pinInSamePlace * 0.000050; // 监听弹窗open事件,确保DOM已渲染完成再绑定事件 popup.on('open', () => { const opensmsBtn = popup.getElement().querySelector("button.o-map-renderer--popup-buttons-send_sms"); if (opensmsBtn) { // 用addEventListener替代onclick,避免覆盖其他事件 opensmsBtn.addEventListener('click', () => { L.popup({ offset: [0, -30] }) .setLatLng([ partner.partner_latitude + latLongOffset, partner.partner_longitude - latLongOffset, ]) .setContent(popupHtml1) .openOn(this.leafletMap); }); } }); // 可选:事件委托方案(更适配动态更新的弹窗内容) const popupElement = popup.getElement(); popupElement.addEventListener('click', (e) => { if (e.target.matches("button.o-map-renderer--popup-buttons-send_sms")) { L.popup({ offset: [0, -30] }) .setLatLng([ partner.partner_latitude + latLongOffset, partner.partner_longitude - latLongOffset, ]) .setContent(popupHtml1) .openOn(this.leafletMap); } }); return popup; } }
关键改进点
- 延迟绑定事件:通过监听Leaflet弹窗的
open事件,确保弹窗DOM完全渲染后再查找按钮元素。 - 使用
addEventListener:替代onclick属性,避免覆盖其他可能存在的事件绑定。 - 事件委托(可选):将事件绑定到弹窗父元素,即使按钮被动态重新渲染,事件依然有效。
内容的提问来源于stack exchange,提问作者M Tahir Noor
相关产品推荐
相关产品推荐

