我有一个Reagent原子:
(defonce order (r/atom {:firstName "" :lastName "" :toppings [] }))
我想在:toppings
向量中添加浇头。我尝试了很多变化:
(swap! (:toppings order) conj "Pepperoni")
给了我:Uncaught Error: No protocol method ISwap.-swap! defined for type null:
(swap! order :toppings "Pepperoni")
有点工作,但只是更新顺序,而不是:toppings
向量。当我deref order
时,我得到了最新的价值。
向:toppings
向量添加(和删除)值的正确方法是什么?
答案 0 :(得分:5)
只是为了解释一下,当你(swap! (:toppings order) ...)
时,你正在从:toppings
检索order
密钥,如果它是一张地图就会有意义,但它是&#39} ; s是一个原子,所以(:toppings order)
返回nil
。
swap!
的第一个参数应始终为原子(Reagent
原子以相同的方式工作)。第二个参数应该是一个以atom的内容为第一个参数的函数。然后,您可以选择提供更多将传递给函数参数的参数。
您可以执行以下操作,而不是minhtuannguyen的答案:
(swap! order
(fn a [m]
(update m :toppings
(fn b [t]
(conj t "Pepperoni")))))
fn a
接收原子内的地图,将其绑定到m
,然后更新它并返回一个新的地图,它将成为原子的新值。
如果您愿意,可以重新定义fn a
以获取第二个参数:
(swap! order
(fn a [m the-key]
(update m the-key
(fn b [t]
(conj t "Pepperoni"))))
:toppings)
:toppings
现在作为fn a
的第二个参数传递,然后传递到update
内的fn a
。我们可以对update
的第三个参数执行相同的操作:
(swap! order
(fn a [m the-key the-fn]
(update m the-key the-fn))
:toppings
(fn b [t]
(conj t "Pepperoni")))
现在update
与fn a
具有相同的签名,因此我们根本不再需要fn a
。我们可以直接代替update
:
fn a
(swap! order update :toppings
(fn b [t]
(conj t "Pepperoni")))
但我们可以坚持下去,因为update
也接受更多的参数,然后传递给提供给它的函数。我们可以重写fn b
以获取另一个论点:
(swap! order update :toppings
(fn b [t the-topping]
(conj t the-topping))
"Pepperoni"))
conj
再次与fn b
具有相同的签名,因此fn b
是多余的,我们可以在其位置使用conj
:
(swap! order update :toppings conj "Pepperoni")
因此,我们最终得到了minhtuannguyen的答案。
答案 1 :(得分:4)
您可以使用以下命令更新配料:
(swap! order update :toppings conj "Pepperoni")
答案 2 :(得分:4)