swap! 是什么意思? with assoc 和 (-> % .-target .-value) 语法在 ClojureScript 中是什么意思?
What does swap! with assoc and (-> % .-target .-value) syntax mean in ClojureScript?
我正在尝试理解 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)
尤其是这个:
...(-> % .-目标 .-值)
#()
是一个 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)
表示获取对象X
.
的属性target
所以你定义了一个接收单个参数的匿名函数。此函数将更改 fields
原子,以便其键 :name
将设置为 属性 [=19 中对象的 属性 value
的值=] 对象 X
.
在你的问题中,swap!
接受一个原子,一个函数 (assoc
) 更新原子存储 和 后续参数的值到功能。
这是实现相同结果的另一种方法:
#(swap! fields (fn [prev] (assoc prev :name (-> % .-target .-value)))
看到 :name
和 (-> % .-target .-value)
将是您问题的 swap!
调用中的两个后续参数,其中 apply
在内部用于将这些参数应用于assoc
。这里只有一个更新函数 - 没有后续参数。
如您所见,prev
是我们要更改的原子的内部值,swap!
只需要一个 'updating' 函数,returns要存储的 swap!
的下一个值。
就 (-> % .-target .-value)
而言,请记住您已经在 reader 宏中,因此 %
是它的第一个参数。 ->
线程宏线程进入每个后续函数的第一个参数,因此 %
被提供给 .-target
,然后其结果被提供给 .-value
,给我们: (.-value (.-target %))
.
:name
存储在字段中的映射被设置为所提供的某个值的目标值!
稍微宽一点 %
是一个 JavaScript 事件,每当文本输入字段更改时都会提供 - 基本上每当用户键入文本时。您很少需要整个事件 - 只需要输入的文本,这是获取事件目标(而不是源)然后该目标值的地方。 .-
部分意味着您得到的是 JavaScript 属性 - 这是 'interop',与正常的 ClojureScript 语法相反。
[:input {:on-change #(swap! fields assoc :name (-> % .-target .-value)}]
这定义了一个输入和一个函数,每次用户更改输入字段时都会调用该函数,即。 e.输入它。该函数将以更改事件对象作为参数调用,然后绑定到 %
。事件目标是输入字段 DOM 元素,其文本内容为 value
。然后该函数更改 fields
以包含 :name
该内容。
#(…)
和 %
属于同一类:#(…)
创建一个匿名函数,%
是其参数的名称。
->
是一个宏,它将通常的 lispy 形式的前缀组合反转为类似于后缀组合的东西或 "piping":(-> % .-target .-value)
扩展为 (.-value (.-target %))
。
.-value
符号是 ClojureScript 中的 JavaScript 互操作。表示访问JavaScript对象的"value"字段; ClojureScript 中的 (.-value foo)
与 JavaScript 中的 foo.value
或 foo["value"]
基本相同。
我正在尝试理解 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)
尤其是这个: ...(-> % .-目标 .-值)
#()
是一个 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)
表示获取对象X
.
target
所以你定义了一个接收单个参数的匿名函数。此函数将更改 fields
原子,以便其键 :name
将设置为 属性 [=19 中对象的 属性 value
的值=] 对象 X
.
在你的问题中,swap!
接受一个原子,一个函数 (assoc
) 更新原子存储 和 后续参数的值到功能。
这是实现相同结果的另一种方法:
#(swap! fields (fn [prev] (assoc prev :name (-> % .-target .-value)))
看到 :name
和 (-> % .-target .-value)
将是您问题的 swap!
调用中的两个后续参数,其中 apply
在内部用于将这些参数应用于assoc
。这里只有一个更新函数 - 没有后续参数。
如您所见,prev
是我们要更改的原子的内部值,swap!
只需要一个 'updating' 函数,returns要存储的 swap!
的下一个值。
就 (-> % .-target .-value)
而言,请记住您已经在 reader 宏中,因此 %
是它的第一个参数。 ->
线程宏线程进入每个后续函数的第一个参数,因此 %
被提供给 .-target
,然后其结果被提供给 .-value
,给我们: (.-value (.-target %))
.
:name
存储在字段中的映射被设置为所提供的某个值的目标值!
稍微宽一点 %
是一个 JavaScript 事件,每当文本输入字段更改时都会提供 - 基本上每当用户键入文本时。您很少需要整个事件 - 只需要输入的文本,这是获取事件目标(而不是源)然后该目标值的地方。 .-
部分意味着您得到的是 JavaScript 属性 - 这是 'interop',与正常的 ClojureScript 语法相反。
[:input {:on-change #(swap! fields assoc :name (-> % .-target .-value)}]
这定义了一个输入和一个函数,每次用户更改输入字段时都会调用该函数,即。 e.输入它。该函数将以更改事件对象作为参数调用,然后绑定到 %
。事件目标是输入字段 DOM 元素,其文本内容为 value
。然后该函数更改 fields
以包含 :name
该内容。
#(…)
和 %
属于同一类:#(…)
创建一个匿名函数,%
是其参数的名称。
->
是一个宏,它将通常的 lispy 形式的前缀组合反转为类似于后缀组合的东西或 "piping":(-> % .-target .-value)
扩展为 (.-value (.-target %))
。
.-value
符号是 ClojureScript 中的 JavaScript 互操作。表示访问JavaScript对象的"value"字段; ClojureScript 中的 (.-value foo)
与 JavaScript 中的 foo.value
或 foo["value"]
基本相同。