重新构建:在嵌套向量中添加新的地图元素
re-frame: adding a new map element in nested vector
我的 "db" 中有这个结构(有序映射),关键字为“:questions”:
{:33 {:question "one", :id 33, :answers [{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]}},
{:39 {:question "two", :id 39, :answers []}},
{:41 {:question "three", :id 41, :answers [{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}
我可以在事件处理程序中添加一个新问题 "re-frame/reg-event-db" 添加:
(assoc-in db [:questions (:id response)] new-map-stuff)
但我不知道如何在“:answers”键中添加地图。此外,恐怕每次添加新答案时我都会渲染所有问题。
我读到了 "path" 拦截器(有点像 "update-in"),但找不到有关如何使用它的示例。
就像在普通的 clojure 中一样,使用 update-in
。首先从 Clojure CheatSheet 开始:
http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html
或 ClojureScript 版本:http://cljs.info
查看 update-in
的文档:https://clojuredocs.org/clojure.core/update-in
您需要 2 个组件
- 导航突变位点的路径
- 根据 (1).
中的点执行突变 的函数
您没有完全指定您的数据。我假设它看起来像这样:
(def db {:questions [
{:33 {:question "one", :id 33,
:answers [{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]}},
{:39 {:question "two", :id 39, :answers []}},
{:41 {:question "three", :id 41,
:answers [{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}]})
我会补一张新的answer
地图来补充:
(def new-answer {:id 42, :question_id 442, :answer "The Ultimate", :correct false})
这段代码分段显示了这个过程。
(let [submap (get-in db [:questions 0 :33 :answers])
modified (conj submap new-answer)
final-answer (update-in db [:questions 0 :33 :answers] conj new-answer) ]
首先导航得到submap
:
submap =>
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]
以及您添加新答案的方式:
modified =>
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}
{:id 42, :question_id 442, :answer "The Ultimate", :correct false}]
然后将它们全部整合到一个操作中:
final-answer =>
{:questions
[{:33
{:question "one",
:id 33,
:answers
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}
{:id 42, :question_id 442, :answer "The Ultimate", :correct false}]}}
{:39 {:question "two", :id 39, :answers []}}
{:41
{:question "three",
:id 41,
:answers
[{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}]}
所有这些在 ClojureScript 中的工作方式与在 Clojure 中的相同。
不用担心使用 path
拦截器。我认为它使事情变得混乱多于帮助。不要担心渲染速度,除非:
- 您已经使用并测试了它,并且知道它是正确的。
- 您已经测量了渲染速度并且可以记录存在问题和您需要加速的数量。
- 对于长列表,请查看
key
元数据,您可以将其添加到试剂的每个列表元素中。参见:
更新
请注意,显示 submap
和 modified
仅用于演示目的 以展示 update-in
有效。 update-in
表达式是您实际包含在代码中的唯一内容。另外,请注意 update-in
仅使用 db
和 new-answer
.
我的 "db" 中有这个结构(有序映射),关键字为“:questions”:
{:33 {:question "one", :id 33, :answers [{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]}},
{:39 {:question "two", :id 39, :answers []}},
{:41 {:question "three", :id 41, :answers [{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}
我可以在事件处理程序中添加一个新问题 "re-frame/reg-event-db" 添加:
(assoc-in db [:questions (:id response)] new-map-stuff)
但我不知道如何在“:answers”键中添加地图。此外,恐怕每次添加新答案时我都会渲染所有问题。
我读到了 "path" 拦截器(有点像 "update-in"),但找不到有关如何使用它的示例。
就像在普通的 clojure 中一样,使用 update-in
。首先从 Clojure CheatSheet 开始:
http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html
或 ClojureScript 版本:http://cljs.info
查看 update-in
的文档:https://clojuredocs.org/clojure.core/update-in
您需要 2 个组件
- 导航突变位点的路径
- 根据 (1). 中的点执行突变 的函数
您没有完全指定您的数据。我假设它看起来像这样:
(def db {:questions [
{:33 {:question "one", :id 33,
:answers [{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]}},
{:39 {:question "two", :id 39, :answers []}},
{:41 {:question "three", :id 41,
:answers [{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}]})
我会补一张新的answer
地图来补充:
(def new-answer {:id 42, :question_id 442, :answer "The Ultimate", :correct false})
这段代码分段显示了这个过程。
(let [submap (get-in db [:questions 0 :33 :answers])
modified (conj submap new-answer)
final-answer (update-in db [:questions 0 :33 :answers] conj new-answer) ]
首先导航得到submap
:
submap =>
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]
以及您添加新答案的方式:
modified =>
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}
{:id 42, :question_id 442, :answer "The Ultimate", :correct false}]
然后将它们全部整合到一个操作中:
final-answer =>
{:questions
[{:33
{:question "one",
:id 33,
:answers
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}
{:id 42, :question_id 442, :answer "The Ultimate", :correct false}]}}
{:39 {:question "two", :id 39, :answers []}}
{:41
{:question "three",
:id 41,
:answers
[{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}]}
所有这些在 ClojureScript 中的工作方式与在 Clojure 中的相同。
不用担心使用 path
拦截器。我认为它使事情变得混乱多于帮助。不要担心渲染速度,除非:
- 您已经使用并测试了它,并且知道它是正确的。
- 您已经测量了渲染速度并且可以记录存在问题和您需要加速的数量。
- 对于长列表,请查看
key
元数据,您可以将其添加到试剂的每个列表元素中。参见:
更新
请注意,显示 submap
和 modified
仅用于演示目的 以展示 update-in
有效。 update-in
表达式是您实际包含在代码中的唯一内容。另外,请注意 update-in
仅使用 db
和 new-answer
.