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 的使用。下面的最终结果(这是带有轻微 mod 的 Joost 答案):

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

3 回答 3

5

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

如果您想在返回的序列中一次放入两个项目for,请将它们放入一个向量中,然后再将它们解包。

虽然我个人更喜欢 mapcat 用于这些情况。就像是:

(into (form-to [:post (format "/dataset/table/%s" id)])
  (mapcat #(vector (drop-down % (nms %)) [:br]) nms))
于 2011-11-12T10:46:11.480 回答
1

我整理了一些不使用 Noir 或 hiccup 的东西,但也许会引导你朝着更好的方向前进。它使用 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])
于 2011-11-12T10:52:27.007 回答
0

Hiccup 会自动为您“解包”序列/列表(不是向量!),因此您可以将其写为:

(for [[k v] nms]
  (list (drop-down k v)
        [:br])))
于 2011-11-14T02:13:53.443 回答