Clojure使用(for)与hiccup和noir

4

我正在使用Clojure和Hiccup(与Noir一起),我有以下代码:

(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个回答

5

这段代码甚至无法编译; for 需要 恰好两个 参数。

如果你想同时将两个项目放入由 for 返回的序列中,请将它们放入向量中,然后在稍后进行拆包。

尽管个人更喜欢在这些情况下使用 mapcat。类似于:

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

1

我做了一点小东西,它不使用Noir或hiccup,但也许会指导你更好的方向。它使用mapcat而不是for:

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

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

谢谢。这帮助我更好地理解了mapcat。 - kfk

0
Hiccup会自动为您“解包”序列/列表(不包括向量!),因此您可以将其编写为:
(for [[k v] nms]
  (list (drop-down k v)
        [:br])))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接