Реагентный компонент в Leaflet Popup - Настройка Leaflet Popup

Я создаю интерфейс Clojurescript с помощью Re-Frame и Reagent. На данный момент интерфейс содержит только карту, созданную с помощью 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 как строку. Я хочу записать содержимое всплывающего окна в синтаксисе икота, а затем передать его каким-то образом в ".bindPopup". Я хочу сделать это, потому что при нажатии будет содержаться некоторый Clojurescript, который я не смогу вставить туда, если я просто напишу HTML-строку в виде строки. Я пробовал например с:
(.bindPopup (reagent.dom.server/render-to-string [:div "Hello World"]))
И это тоже хорошо работает, но любой щелчок, который я нажимаю, теряется в переводе. Я знаю, что это не работает таким образом (см., Что обработчик onClick не регистрируется в ReactDOMServer.renderToString или React.js для рендеринга на стороне сервера и обработчиков событий).

Поэтому я хочу найти другой способ передачи моего компонента Reagent (который просто оборачивает React) в Leaflet, чтобы он удовлетворял интерфейсу всплывающего окна:
setContent(<String|HTMLElement|Function> htmlContent) ( https://leafletjs.com/reference-1.3.2.html)

Поэтому в основном я хочу визуализировать компонент в HTMLElement, а не напрямую в виртуальный DOM. Я хочу вызвать функцию рендеринга реагентов и не рендерить результат в приложение, а вернуть его как HTMLElement, который я могу передать Leaflet.

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

TLDR: Как я могу отобразить компонент Reagent в HTML-элемент, включая его функцию "по щелчку", чтобы я мог передать это во всплывающее окно Leaflet?

Любая помощь приветствуется.

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)))))
Другие вопросы по тегам