nen*_*nad 6 clojure 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"}]])))
Run Code Online (Sandbox Code Playgroud)
谁能解释一下这部分:
#(swap! fields assoc :name (-> % .-target .-value)
Run Code Online (Sandbox Code Playgroud)
尤其是这个: ...(-> % .-target .-value)
[:input {:on-change #(swap! fields assoc :name (-> % .-target .-value)}]\nRun Code Online (Sandbox Code Playgroud)\n\n这定义了一个输入和一个函数,每次用户更改输入字段(即在其中键入内容)时都会调用该函数。该函数将以更改事件对象作为参数调用,然后将其绑定到%. 事件目标是输入字段 DOM 元素,value其文本内容为文本内容。然后该函数将更改为fields包含:name该内容。
the#(\xe2\x80\xa6)和 the%属于一起:#(\xe2\x80\xa6)创建一个匿名函数,并且%是其参数的名称。
这->是一个宏,它将通常的 lispy 前缀组合形式反转为类似于后缀组合或“管道”的东西:(-> % .-target .-value)扩展为(.-value (.-target %)).
该.-value表示法是 ClojureScript 中的 JavaScript 互操作。它表示对 JavaScript 对象的字段“值”的访问;ClojureScript 本质上与JavaScript 中的(.-value foo)书写相同。foo.valuefoo["value"]
在你的问题中swap!,采用一个原子,一个函数(assoc),它更新原子存储的值以及赋予该函数的后续参数。
这是实现相同结果的另一种方法:
#(swap! fields (fn [prev] (assoc prev :name (-> % .-target .-value)))
Run Code Online (Sandbox Code Playgroud)
请参阅:name和将是调用您的问题(-> % .-target .-value)时的两个后续参数,其中在内部使用将这些参数应用于. 这里只有一个更新函数 - 没有后续参数。swap!applyassoc
正如您所看到的,prev我们要更改的原子的内部值swap!仅采用“更新”函数,该函数返回要swap!存储的下一个值。
就目前而言(-> % .-target .-value),请记住您已经在阅读器宏中,因此%它的第一个参数也是如此。线程->宏线程进入以下每个函数的第一个参数,因此%被赋予.-target,然后其结果被赋予.-value,给我们:(.-value (.-target %))。
:name存储在字段中的地图中被设置为所提供的某个值的目标值!
更广泛的%是,只要文本输入字段发生更改(基本上是用户键入文本),就会提供 JavaScript 事件。您很少需要整个事件 - 只需输入已键入的文本,这是获取事件目标(而不是源)以及该目标值的地方。该部分意味着.-您正在获取 JavaScript property - 这是“互操作”,与普通的 ClojureScript 语法相反。