Clojure使用(for)打嗝和黑色

时间:2011-11-12 10:01:20

标签: clojure hiccup noir

我正在使用clojure和打嗝(黑色),我有这个代码:

(defn dataframe [id]
   (db/db-to-data id))

(defpartial drop-downs [nms]
  (for [nm (keys nms)] (drop-down nm (get nms nm))[:br])
  (submit-button "Refresh")  
  )

(defpage "/dataset/table/:id" {:keys [id]}
  (common/layout
    (form-to [:post (format "/dataset/table/%s" id)]
      (drop-downs {"alessio" [:col0], "test" [:col1]})
      )
   (html-table (dataframe id))))

我的问题是:

(for [nm (keys nms)] (drop-down nm (get nms nm))[:br])

我希望在我的表单中有多个选择。上面这一行就是这样,但由于某些原因,它不考虑[:br],所以它不会破坏这些行。但是,如果我这样做:

(form-to [:post (format "/dataset/table/%s" id)]
      (drop-down "Test1" "1")[:br]
      (drop-down "Test2" "2")[:br]
      )

[:br]标签确实有效。我相信这与(for)宏如何工作有关,但我无法弄清楚原因以及如何解决它。

修改

根据建议,我放弃使用for。下面的最终结果(Joost以轻微模式回答):

(mapcat #(vector (drop-down % (nms %)) [:br]) (keys nms))

3 个答案:

答案 0 :(得分:5)

该代码甚至无法编译; for正好使用两个参数。

如果你想在for返回的序列中同时放置两个项目,请将它们放在一个向量中,然后再解压缩。

虽然我个人更喜欢mapcat用于这些情况。类似的东西:

(into (form-to [:post (format "/dataset/table/%s" id)])
  (mapcat #(vector (drop-down % (nms %)) [:br]) nms))

答案 1 :(得分:1)

我把一些不使用Noir或打嗝的东西放在一起,但也许会引导你朝着更好的方向前进。它使用mapcat而不是:

 (let [nms {"alessio" [:col0], "test" [:col1]}]
  (mapcat 
    (fn [mapentry] [[:dropdown (first mapentry) (second mapentry)] [:br]]) nms))

;;=> ([:dropdown "alessio" [:col0]] [:br] [:dropdown "test" [:col1]] [:br])

答案 2 :(得分:0)

打嗝会自动“解开”seqs / lists(不是矢量!),所以你可以这样写:

(for [[k v] nms]
  (list (drop-down k v)
        [:br])))