交换什么! ClojureScript中具有assoc和(->%.-target .-value)语法的意思?

时间:2018-08-18 17:11:54

标签: 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"}]]))) 

有人可以解释这部分吗?

#(swap! fields assoc :name (-> % .-target .-value)

尤其是:     ...(->%.-target .-value)

3 个答案:

答案 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.valuefoo["value"]基本上相同。