2012-05-15 111 views
3

欲遍历表示打嗝数据结构的载体树:遍历矢量树

[:div {:class "special"} [:btn-grp '("Hello" "Hi")]] 

然后我想派遣于载体上的关键字,如果多重方法已为关键字定义,然后它会返回另一组矢量,它将替换原始标记。

例如,上述结构会被变换为:

[:div {:class "special"} [:div [:button "Hello"] [:button "Hi"]]] 

定制多重方法将收到列表(“你好”,“喜”)作为参数。它会返回包含按钮的div。

我如何写穿越载体与形式作为参数一切分派的关键字,然后返回的形式代替当前形式的功能?

回答

1
(ns customtags 
    (:require [clojure.walk :as walk])) 

(def customtags (atom {})) 

(defn add-custom-tag [tag f] 
    (swap! customtags assoc tag f)) 

(defn try-transform [[tag & params :as coll]] 
    (if-let [f (get @customtags tag)] 
    (apply f params) 
    coll)) 

(defmacro defcustomtag [tag params & body] 
    `(add-custom-tag ~tag (fn ~params [email protected]))) 

(defn apply-custom-tags [coll] 
    (walk/prewalk 
    (fn [x] 
     (if (vector? x) 
     (try-transform x) 
     x)) coll)) 

使用它:

(require '[customtags :as ct]) 
(ct/defcustomtag :btn-grp [& coll] (into [:div] (map (fn [x] [:button x]) coll))) 
(ct/defcustomtag :button [name] [:input {:type "button" :id name}]) 

(def data [:div {:class "special"} [:btn-grp "Hello" "Hi"]]) 

(ct/apply-custom-tags data) 
[:div {:class "special"} [:div [:input {:type "button", :id "Hello"}] [:input {:type "button", :id "Hi"}]]] 
+0

丹妮,感谢您的答复。然而,为什么你说把整棵树表示为一个数据结构是没有价值的。打嗝会为表格带来价值,因为您可以将HTML树作为矢量树来操作,如果自定义标签也可以同样呈现,它会有帮助吗?我本着学习的精神问这个问题,所以请让我知道你的意见。 – murtaza52

+0

我明白你的观点。更新我的回复。 – DanLebrero

+0

感谢伟大的代码! – murtaza52