Leaflet Popup中的试剂成分-自定义Leaflet Popup

时间:2018-07-29 14:10:12

标签: javascript leaflet clojurescript reagent re-frame

我正在使用Re-Frame和Reagent构建Clojurescript前端。目前,前端仅包含使用Leaflet创建的地图。在地图上单击后,将在该位置设置一个新标记。单击任何这些标记时,都会显示一个弹出窗口。

到目前为止,一切都很好。现在的问题是,我想精确调整此Leaflet弹出窗口以包含一个删除按钮,然后应使用该按钮再次删除标记。这是我遇到问题的地方。该代码如下所示(精简到最小):

(setup-map!
    (-> js/L
        (.map "mapid")
        (.setView #js [12.34 56.78] 10))]
        (.on map "click" add-marker-to-map! (aget % "latlng" "lat") (aget % 
        "latlng" "lng"))))  

(defn add-marker-to-map!
    [lat long map-object]
    (-> js/L
        (.marker #js [lat long])
        (.addTo map-object)
        (.bindPopup "<div>Hello World!</div>")

这也可以解决。但是我不想将内联HTML编写为字符串。我想用打syntax语法编写弹出窗口的内容,然后以某种方式将其传递给“ .bindPopup”。我想这样做,因为单击时将包含一些Clojurescript,如果我只是将HTML内联代码编写为字符串,则无法在其中放入。 我尝试了例如:
(.bindPopup (reagent.dom.server/render-to-string [:div "Hello World"]))
这也很好用,但是我在其中输入的任何单击都会丢失翻译。我知道这不是这种方式(请参阅onClick handler not registering with ReactDOMServer.renderToStringReact.js Serverside rendering and Event Handlers)。

因此,我想找到另一种方法来将我的Reagent(仅包装React)组件传递给Leaflet,使其满足弹出窗口的接口:
setContent(<String|HTMLElement|Function> htmlContent)https://leafletjs.com/reference-1.3.2.html#popup-setcontent

所以基本上我想将组件呈现为HTMLElement而不是直接呈现为虚拟DOM。我想调用试剂渲染函数,而不将结果渲染到应用程序中,而是将其作为HTMLElement返回,可以传递给Leaflet。

 (reagent/render [hello] (.getElementById js/document "app"))

TLDR:如何将Reagent组件呈现到包含其单击功能的HTMLelement中,以便可以将其移交给Leaflet弹出窗口?

任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

您可以使用自己的DOM容器来呈现元素:

(def custom-parent (atom (dom/createDom "div")))

我假设您需要的不止一个,但是为了简洁起见,我只需要一个。

(defn add-marker-to-map!
    [evt]
    (let [evt (js->clj evt :keywordize-keys true)
          {{:keys [lat lng]} :latlng} evt]
        (-> js/L
            (.marker #js [lat lng])
            (.addTo m)
            (.bindPopup (r/render [:div "Marker here"
                                   [:br]
                                   [:button {:on-click (fn [] (js/console.log "clicked"))} "delete me"]]
                                  @custom-parent)))))