我想创建一个默认隐藏但用户可以切换该状态的 html 元素列表(其中包括查询结果)。我在下面尝试了几种不同的方法作为玩具示例,但都无法正常工作。
这段代码正确地创建了三个按钮,它们正确地改变了 exps 状态,但从不隐藏内容。
(:require [reagent.core :as r] )
(def exps (r/atom [true true true]))
(defn like-component []
[:div
(for [ [i r] (map-indexed vector ["A" "B" "C"])]
[:div
[:button {:on-click #(swap! exps update-in [i] not)}]
(when (nth @exps i)
[:pre (str i r)])])])
(r/render [like-component]
(js/document.getElementById "app"))
另一方面,下面的代码只会创建一个元素,但它可以正常工作。
(defn expandable-view [e bool]
(let [expanded (r/atom bool)]
(fn []
[:li
[:div.expandable
[:div.header {:on-click #(swap! expanded not)}
"Click me to expand and collapse"]
(if @expanded
[:div.body (allow-html :pre e)])]])))
(defn like-component []
[:ul
(vec
(for [ e ["A" "B" "C"]]
(expandable-view e true ))) ])
(r/render [like-component]
(js/document.getElementById "app"))
编辑:可能相关: https://github.com/reagent-project/reagent/wiki/Beware-Event-Handlers-Returning-False
最佳答案
for
是惰性的,所以 reagent
无法告诉您在第一个代码片段中取消引用 exps
。
我们可以通过显式取消引用原子来解决它。
(defn like-component []
(apply str @exps) ;; because @exps is a vector, and reagent
;; treat vectors as hiccup component
;; we can't just put `@exps` here.
[:div
(for [ [i r] (map-indexed vector ["A" "B" "C"])]
[:div
[:button {:on-click #(swap! exps update-in [i] not)}]
(when (nth @exps i)
[:pre (str i r)])])])
或者只是将惰性序列包装在 doall
中。
(defn like-component []
[:div
(doall (for [ [i r] (map-indexed vector ["A" "B" "C"])]
[:div
[:button {:on-click #(swap! exps update-in [i] not)}]
(when (nth @exps i)
[:pre (str i r)])]))])
仅供引用,related discussions .
any idea why the second block I posted only creates one element?
向量是 Reagent 的特殊公民,它们被视为 hiccup/React 组件。
举个例子
(defn like-component []
[:ul
(doall
(for [ e ["A" "B" "C"]]
[expandable-view e true]))])
另请注意,我们正在使用 [expandable-view e true]
来正确构建试剂成分。
有关更多信息,我强烈建议阅读 Using [] instead of ()和 Creating Reagent Components .
关于clojure - 试剂中的交互式列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32897947/