简体   繁体   English

Clojure - 在不同的函数中更改原子的值

[英]Clojure - Changing the value of an atom in a different function

I know that Clojure is all about immutable data.我知道 Clojure 是关于不可变数据的。 So if you have an atom (say with value 0), the way to change it's value is to de-reference the atom and use swap!所以如果你有一个原子(比如值为 0),改变它的值的方法是取消引用原子并使用交换! or reset!或重置! (say now with value 1). (现在用值 1 说)。 However, globally the atom still has value 0 and in the specific reset!但是,全局原子仍然具有值 0 并且在特定重置中! or swap!或交换! function it has value 1. (I believe this to be correct).函数它的值为 1。(我相信这是正确的)。 My question is, can I have another function that changes the value of the atom which is at 1.我的问题是,我可以有另一个函数来改变原子的值为 1 的值吗?

More clearly更清楚

(def table-data {:headers ["RIC-Code" "Isin" "Currency" "Description"]
                 :rows []})

(defonce fields (atom {}))
(defonce errors (atom nil))
(defonce isin (atom "test")
(defonce tdata (atom table-data))


(defn get-ric [ric isin]
  (GET "/search-isin"
       {:params {:ric ric}
        :headers {"Accept" "application/transit+json"}
        :handler #(do
                   (.log js/console (str "get-msg response : " %))
                   (reset! isin %)
                   (reset! tdata {:headers ["RIC-Code" "Isin" "Currency" "Description"]
                                  :rows    @isin}))}))



(defn replace-value [struct]
  (walk/prewalk-replace {"id" "name"} struct))
(defn isin-form2 [isin]
  [:div.content
   [errors-component errors :server-error]
   [:div.form-group
    [errors-component errors :name]
    [:p "Enter RIC-Code:"
     [:input.form-control
      {:type      :text
       :name      :ric
       :on-change #(swap! fields assoc :ric (-> % .-target .-value))
       :value     (:ric @fields)}]]
    [errors-component errors :message]
    [:input.btn.btn-primary
     {:type     :submit
      :on-click #(do
                  (get-ric (:ric @fields) isin))
      :value    "Search RIC-Code"}]
    [rt/reagent-table tdata]
    [:input.btn.btn-primary
     {:type     :submit
      :on-click #(do
                  (reset! tdata {:headers ["RIC-Code" "Isin" "Currency" "Description"]
                                 :rows    (swap! isin (replace-value %))}))
      :value    "Change"}]]])

What the above code does, is in isin-form2, it takes an initial value, and sets in into fields with keyword ric.上面的代码所做的,是在 isin-form2 中,它取一个初始值,并设置为关键字 ric 的字段。 The first button calls the get-ric function and returns tdata.第一个按钮调用 get-ric 函数并返回 tdata。 (In get-ric the isin is an atom that is a vector of vectors ie [["id" ...] [...] ... [...]]) What I want the second button to do is swap the value id for name, using replace-value. (在 get-ric 中,isin 是一个原子,它是向量的向量,即 [["id" ...] [...] ... [...]])我想要第二个按钮做的是使用替换值交换名称的值 id。 However in the second button when I try to swap!但是在我尝试交换的第二个按钮中! the value of the isin it is not changing isin 的价值并没有改变

You are not giving swap!你不给swap! a function.一个函数。 Try:尝试:

(swap! isin #(replace-value %))

Perhaps this will explain how it works:也许这将解释它是如何工作的:

(def my-state (atom 0))

(defn fn1 [] 
  (newline)
  (println :fn1-enter @my-state)
  (swap! my-state inc)
  (println :fn1-exit  @my-state)
  (newline))

(defn fn2 [] 
  (newline)
  (println :fn2-enter @my-state)
  (swap! my-state inc)
  (println :fn2-exit  @my-state)
  (newline))

(println :main-1 @my-state)
(fn1)
(println :main-2 @my-state)
(fn2)
(println :main-3 @my-state)

with result结果

:main-1 0

:fn1-enter 0
:fn1-exit 1

:main-2 1

:fn2-enter 1
:fn2-exit 2

:main-3 2

I was having a similar problem with the atom not changing it's value across different functions (ie, the value would be changed in one place, and I needed that result on the other), so I ended up defining the atom globally.我有一个类似的问题,原子没有在不同的函数中改变它的值(即,值会在一个地方改变,而我需要在另一个地方得到这个结果),所以我最终全局定义了原子。 While this isn't probably the ideal solution, I think this can work in cases when you don't have issues with it being declared that way!虽然这可能不是理想的解决方案,但我认为这可以在您以这种方式声明它没有问题的情况下起作用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM