重新构图:在嵌套向量中添加新的地图元素

时间:2018-10-11 02:02:18

标签: clojurescript reagent re-frame

我在“ 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”键中添加地图。此外,我担心每次添加新答案时都会渲染所有问题。

我阅读了有关“路径”拦截器(种类为“ update-in”)的信息,但找不到有关如何使用它的示例。

1 个答案:

答案 0 :(得分:1)

您可以像使用普通intent?.extras?.getString(ARG_TEMPLATE_CODE) 一样简单地进行此操作。首先从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. 导航突变位点的路径
  2. 从(1)点开始执行突变的功能。

您没有完全指定数据。我假设它看起来像这样:

update-in

我将组成一个新的(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}]

所有这些在ClojureScript中的工作方式与Clojure中的相同。

不用担心使用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}]}}]} 拦截器。我认为它使事情变得混乱多于帮助。除非以下条件,否则不必担心渲染速度:

  1. 您已经对其进行了测试并知道它是正确的。
  2. 您已经测量了渲染速度,并可以记录问题 和需要加快的速度。
  3. 要获取长列表,请查看path元数据,您可以将其添加到Reagent的每个列表元素中。参见:Reagent React Clojurescript Warning: Every element in a seq should have a unique :key

更新

请注意, 仅出于演示目的而显示keysubmap ,以展示modified的工作原理。 update-in表达式是您实际要包含在代码中的唯一内容。另外,请注意,update-in 仅使用 update-indb