Clojure - 在不同的函数中更改原子的值
Clojure - Changing the value of an atom in a different function
我知道 Clojure 就是关于不可变数据的。所以如果你有一个原子(比如值为 0),改变它的值的方法是取消引用原子并使用交换!或重置! (现在说值为 1)。但是,全局原子仍然具有值 0 并且在特定重置中!或交换!函数它的值为 1。(我相信这是正确的)。我的问题是,我可以有另一个函数来改变原子的值 1.
更清楚
(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"}]]])
上面代码所做的,是在isin-form2中,它接受一个初始值,并设置到关键字ric的字段中。第一个按钮调用 get-ric 函数和 returns tdata。 (在 get-ric 中,isin 是一个原子,它是向量的向量,即 [["id" ...] [...] ... [...]])我想要第二个按钮要做的是使用替换值将值 id 换成名称。但是在我尝试交换时的第二个按钮中! isin 的值没有改变
你没有给 swap!
一个函数。尝试:
(swap! isin #(replace-value %))
也许这会解释它是如何工作的:
(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)
结果
:main-1 0
:fn1-enter 0
:fn1-exit 1
:main-2 1
:fn2-enter 1
:fn2-exit 2
:main-3 2
我遇到了一个类似的问题,原子没有改变它在不同函数中的值(即值会在一个地方改变,而我需要在另一个地方得到那个结果),所以我最终定义了原子全球范围内。虽然这可能不是理想的解决方案,但我认为这可以在您对以这种方式声明没有问题的情况下起作用!
我知道 Clojure 就是关于不可变数据的。所以如果你有一个原子(比如值为 0),改变它的值的方法是取消引用原子并使用交换!或重置! (现在说值为 1)。但是,全局原子仍然具有值 0 并且在特定重置中!或交换!函数它的值为 1。(我相信这是正确的)。我的问题是,我可以有另一个函数来改变原子的值 1.
更清楚
(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"}]]])
上面代码所做的,是在isin-form2中,它接受一个初始值,并设置到关键字ric的字段中。第一个按钮调用 get-ric 函数和 returns tdata。 (在 get-ric 中,isin 是一个原子,它是向量的向量,即 [["id" ...] [...] ... [...]])我想要第二个按钮要做的是使用替换值将值 id 换成名称。但是在我尝试交换时的第二个按钮中! isin 的值没有改变
你没有给 swap!
一个函数。尝试:
(swap! isin #(replace-value %))
也许这会解释它是如何工作的:
(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)
结果
:main-1 0
:fn1-enter 0
:fn1-exit 1
:main-2 1
:fn2-enter 1
:fn2-exit 2
:main-3 2
我遇到了一个类似的问题,原子没有改变它在不同函数中的值(即值会在一个地方改变,而我需要在另一个地方得到那个结果),所以我最终定义了原子全球范围内。虽然这可能不是理想的解决方案,但我认为这可以在您对以这种方式声明没有问题的情况下起作用!