Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 使用Om,从嵌套映射生成嵌套div_Clojure_Clojurescript_Om - Fatal编程技术网

Clojure 使用Om,从嵌套映射生成嵌套div

Clojure 使用Om,从嵌套映射生成嵌套div,clojure,clojurescript,om,Clojure,Clojurescript,Om,假设我有以下地图: (def m {"a" {"d" {} "e" {}} "b" {"f" {} "g" {"h" {} "i" {}}} "c" {}}) 我需要这样渲染: (om.dom/div #js {} "a" (om.dom/div #js {} "d") (om.dom/div #js {} "e")) (om.dom/div #js {} "b"

假设我有以下地图:

(def m {"a" {"d" {}
             "e" {}}
        "b" {"f" {}
             "g" {"h" {}
                  "i" {}}}
        "c" {}})
我需要这样渲染:

(om.dom/div #js {} "a" 
  (om.dom/div #js {} "d")
  (om.dom/div #js {} "e"))

(om.dom/div #js {} "b" 
  (om.dom/div #js {} "f")
  (om.dom/div #js {} "g"
    (om.dom/div #js {} "h")
    (om.dom/div #js {} "i")))

(om.dom/div #js {} "c")
我该怎么做呢?我把
clojure.walk
弄得一团糟,但无法让它先在叶子上调用
om.dom/div
,然后是直系父母,等等

我认为解决方案可能涉及将递归函数映射到给定子映射的
vals
。它会将地图分开,直到看到一片叶子,然后用气泡将
om.dom/div
调用返回地图

到目前为止,我有这个功能:

(defn build-tree [data]
  (apply dom/div #js {}
         (->> (clojure.walk/postwalk
                #(cond (map? %) (vec %)
                       (vector? %) %
                       (string? %) %) data)
              (clojure.walk/postwalk
                #(if (and (vector? %) (string? (first %)))
                   (apply dom/div #js {} %) %)))))
其结果是:

检查人员中有以下内容:



生成嵌套的
dom/ul
dom/li
元素的额外点数

以下代码生成的DOM结构看起来与您要查找的非常接近,但子节点(即使没有)被包装在
div
中,这应该很容易修复:

(defn tree-component
  [tree]
  (apply dom/div nil
         (keep (fn [[k v]]
                 (when k
                   (dom/div nil k
                            (tree-component v))))
               tree)))

(defn app-view
  [data owner]
  (reify
    om/IRender
    (render [_]
      (tree-component
        {"a" {"d" {}
              "e" {}}
         "b" {"f" {}
              "g" {"h" {}
                   "i" {}}}
         "c" {}}))))

clojure.walk
很棒,但有时会让它更难。我有这个:

 (defn recursive-component [el]
   (cond
    (empty? el) nil
    (vector? el) (apply dom/div nil 
                      (first el)
                      (recursive-component (second el)))
    (map? el) (map recursive-component el)))


 (defn main-component [data owner]
   (om/component
    (apply dom/div nil "Main"
           (recursive-component m))))

对于
ul
li

(defn递归组件[el]
(续)
(和(向量?el)(空的?(第二个el)))
(dom/li nil(第一el))
(矢量?el)(适用于dom/ul nil
(第一页)
(递归分量(第二个el)))
(映射?el)(映射递归分量el)))

但是它显示为
li
元素
{:c{}

在解决此类问题时,有时在REPL处生成类似于所需调用树的树结构会有所帮助。一旦结果看起来正常,将其转换为实际的调用树通常是简单的

例如,这里有一个函数为您的示例生成
om.dom/div
调用树;要在ClojureScript中使用,请按照注释中的指示进行调整:

(defn div [m]
  (for [[k v] m]
    ;; replace with (apply om.dom/div #js {} k (div v)) in CLJS
    (list* 'om.dom/div {} k (div v))))
示例调用:

(div {"a" {"d" {}
           "e" {}}
      "b" {"f" {}
           "g" {"h" {}
                "i" {}}}
      "c" {}})
来自上述方面的输出:

;; in CLJS, you'll want to use this as the ... in
;; (apply create-container-component initial-args ...)
((om.dom/div {} "a"
   (om.dom/div {} "d")
   (om.dom/div {} "e"))
 (om.dom/div {} "b"
   (om.dom/div {} "f")
   (om.dom/div {} "g"
     (om.dom/div {} "h")
     (om.dom/div {} "i")))
 (om.dom/div {} "c"))

这是迄今为止最好的答案。