如何将带有样式的 HTML 标签转换为 Hiccup?反应问题

How to convert HTML tag with style to Hiccup? React problems

我正在尝试将 HTML 和 CSS 解析为 Reagent 项目中的 Hiccup。我正在使用山核桃。当我用内联 CSS 解析 HTML 时,React 抛出异常。

      (map 
         as-hiccup (parse-fragment "<div style='color:red'>test</div>")
      ) 

上面生成 [:div {:style color:red} "test"] & Reactjs returns 来自 Reactjs 的异常:

Violation: The style prop expects a mapping from style properties to values, not a string.

我认为 [:div {:style {"color" "red"}} "test"] 必须返回。

查看代码如下:

(ns main.views.job
  (:require [reagent.core :as reagent :refer [atom]]
                    [hickory.core :refer [as-hiccup parse parse-fragment]]))

(enable-console-print!)

(defn some-view [uid]
  [:div
     (map as-hiccup (parse-fragment "<div style='color:red'>test</div>"))   
  ])

整个存储库 here 并且有效。我在 core.cljs 文件中将样式标签的解析添加到 React 的映射中:

(ns hickory-stack.core
  (:require [clojure.string :as s]
            [clojure.walk :as w]
            [reagent.core :as reagent :refer [atom]]
            [hickory.core :as h]))

(enable-console-print!)

(defn string->tokens
  "Takes a string with syles and parses it into properties and value tokens"
  [style]
  {:pre [(string? style)]
   :post [(even? (count %))]}
  (->> (s/split style #";")
       (mapcat #(s/split % #":"))
       (map s/trim)))

(defn tokens->map
  "Takes a seq of tokens with the properties (even) and their values (odd)
   and returns a map of {properties values}"
  [tokens]
  {:pre [(even? (count tokens))]
   :post [(map? %)]}
  (zipmap (keep-indexed #(if (even? %1) %2) tokens)
          (keep-indexed #(if (odd? %1) %2) tokens)))

(defn style->map
  "Takes an inline style attribute stirng and converts it to a React Style map"
  [style]
  (tokens->map (string->tokens style)))

(defn hiccup->sablono
  "Transforms a style inline attribute into a style map for React"
  [coll]
  (w/postwalk
   (fn [x]
     (if (map? x)
       (update-in x [:style] style->map)
       x))
   coll))

;; Test Data

(def good-style "color:red;background:black; font-style: normal    ;font-size : 20px")

(def html-fragment
  (str "<div style='" good-style "'><div id='a' class='btn' style='font-size:30px;color:white'>test1</div>test2</div>"))

;; Rendering

(defn some-view []
  [:div (hiccup->sablono
         (first (map h/as-hiccup (h/parse-fragment html-fragment))))])

(reagent/render-component [some-view]
                          (. js/document (getElementById "app")))