交换什么!使用 assoc 和 (-> % .-target .-value) 语法在 ClojureScript 中是什么意思?

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)

Sva*_*nte 5

[:input {:on-change #(swap! fields assoc :name (-> % .-target .-value)}]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这定义了一个输入和一个函数,每次用户更改输入字段(即在其中键入内容)时都会调用该函数。该函数将以更改事件对象作为参数调用,然后将其绑定到%. 事件目标是输入字段 DOM 元素,value其文本内容为文本内容。然后该函数将更改为fields包含:name该内容。

\n\n

the#(\xe2\x80\xa6)和 the%属于一起:#(\xe2\x80\xa6)创建一个匿名函数,并且%是其参数的名称。

\n\n

->是一个宏,它将通常的 lispy 前缀组合形式反转为类似于后缀组合或“管道”的东西:(-> % .-target .-value)扩展为(.-value (.-target %)).

\n\n

.-value表示法是 ClojureScript 中的 JavaScript 互操作。它表示对 JavaScript 对象的字段“值”的访问;ClojureScript 本质上与JavaScript 中的(.-value foo)书写相同。foo.valuefoo["value"]

\n


Chr*_*phy 3

在你的问题中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 语法相反。