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

时间:2015-01-31 23:31:49

标签: clojure clojurescript om reagent hiccup

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

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

上述内容会生成[:div {:style color:red} "test"]&amp; Reactjs从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>"))   
  ])

1 个答案:

答案 0 :(得分:2)

整个回购是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")))