我正在尝试理解Web Development With Clojure书中的这段代码。关于clojure脚本:
(defn message-form []
(let [fields (atom {})]
(fn []
[:div.content
[:div.form-group
[:p "Name:"
[:input.form-control
{:type :text
:name :name
:on-change #(swap! fields assoc :name (-> % .-target .-value))
:value (:name @fields)}]]]
[:p "Message:"
[:textarea.form-control
{:rows 4
:cols 50
:name :message
:on-change #(swap! fields assoc :message (-> % .-target .-value))}
(:message @fields)]]
[:input.btn.btn-primary {:type :submit :value "comment"}]])))
有人可以解释这部分吗?
#(swap! fields assoc :name (-> % .-target .-value)
尤其是: ...(->%.-target .-value)
答案 0 :(得分:2)
#()
是reader macro。这是匿名函数(fn [args] ...)
的缩写,其中%
是该函数的第一个参数。
在这种情况下,#(swap! fields assoc :name (-> % .-target .-value)
等于(fn [X] (swap! fields assoc :name (-> X .-target .-value))
->
是threading macro,而(-> X .-target .-value)
等效于(.-value (.-target X))
。
(.-target X)
表示获取对象target
的属性X
。
因此,您定义了一个接收单个参数的匿名函数。此函数将更改fields
原子,以便将其键:name
设置为对象{{1的属性value
中对象的属性target
的值}}。
答案 1 :(得分:2)
在您的问题swap!
中,有一个原子(一个函数(assoc
)用于更新原子存储的值,该值存储给该函数的和后继参数。
这是获得相同结果的另一种方法:
#(swap! fields (fn [prev] (assoc prev :name (-> % .-target .-value)))
请注意,:name
和(-> % .-target .-value)
将是问题的swap!
调用中的两个后续参数,其中apply
在内部用于将这些参数应用于{{ 1}}。这里只有一个更新功能-没有后续参数。
如您所见,assoc
是我们要更改的原子的内部值,prev
仅采用“更新”功能,该函数返回swap!
的下一个值储藏。
就swap!
而言,请记住您已经在reader宏中,因此(-> % .-target .-value)
是它的第一个参数。 %
线程宏线程进入每个后续函数的第一个参数,因此将->
赋予%
,然后将其结果赋予.-target
,从而得到: .-value
。
(.-value (.-target %))
设置为要提供的某个值的目标值!
更宽泛的:name
是一个JavaScript事件,只要更改文本输入字段(基本上在用户键入文本时)就会提供此事件。您很少需要整个事件-仅输入要键入的文本,这是获取事件目标(而不是源)以及目标值的地方。%
部分的意思是您将获得一个JavaScript属性-与常规ClojureScript语法相反,这是“互操作”。
答案 2 :(得分:1)
[:input {:on-change #(swap! fields assoc :name (-> % .-target .-value)}]
这定义了输入和每次用户更改输入字段(即i)时都会调用的函数。 e。输入。该函数将以change事件对象作为参数来调用,然后将其绑定到%
。事件目标是输入字段DOM元素,其文本内容为value
。然后,该函数将fields
更改为包含:name
的内容。
#(…)
和%
属于一起:#(…)
创建一个匿名函数,而%
是其参数的名称。
->
是一个宏,它可以将表格的常用前缀前缀组成转换为类似于后缀组成或“管道”的内容:(-> % .-target .-value)
扩展为(.-value (.-target %))
。
.-value
表示法是ClojureScript中的JavaScript互操作。它表示对JavaScript对象的字段“值”的访问; ClojureScript中的(.-value foo)
与用JavaScript编写foo.value
或foo["value"]
基本上相同。