我想为 Om 组件创建一个点击处理函数。我发现的文档和堆栈溢出示例总是像这样声明匿名函数

(defn main-view [_ owner]
  (reify
  om/IRender
   (render [_]
    (let [xs (items)]
      (dom/div nil
        (om/build sub-view {:title "View A"})
        (om/build sub-view {:title "View B"})
        (dom/button
          #js {:onClick
               (fn [e] (om/transact! xs #(assoc % 1 {:text "zebra"})))}
          "Switch To Zebra!"))))))

我认为在 jsx/template 区域之外,在组件内声明点击函数会更清晰,就像在常规 React 中通常所做的那样。有没有办法在组件内的 Om 中做到这一点?我试过这个,但它不起作用,因为 onClick 是未定义的:
(defn my-component []
  (reify
    om/IRender
    (render [this]
       ; Using Sablono syntax
       (html [:h1 "Here is a heading" {:on-click 'onClick} ]))
    onClick
    (onClick [this]
      ; this part never gets executed when you click
      (.log js/console "click"))))

如果可能的话,我想避免在组件之外定义一个单独的函数。

最佳答案

你的问题是明智的,它是关于处理数据范围的。

这是可能的,但这种方法的问题在大多数情况下您将需要来自外部代码块的本地范围数据(在您的情况下,它是一个 Om 组件)。

我会在代码中解释。假设您想将处理程序函数移出:

(anything
 (let [a 1 b 2]
   (on-event (fn my-handler [evt] (log (+ a b (.someAttr evt)))))))

你最终会得到这个更长的时间:
(defn local-data->handler [a b]
  (fn [evt] (log (+ a b (.someAttr evt)))))

(anything
 (let [a 1 b 2]
   (on-event (local-data->handler a b))))

如果您只想在组件定义中移动:
(anything
 (let [a 1
       b 2
       my-handler (fn [evt] (log (+ a b (.someAttr evt))))]
   (on-event my-handler)))

请注意:为了保持事件处理程序的工作,请确保您的非匿名函数(使用 defn 或 let 创建)与匿名形式相同,尤其是参数列表。

onClick 是未定义的,因为您将其用作 Om 协议(protocol)。请查阅 Om 生命周期协议(protocol)以正确使用。

https://github.com/swannodette/om/wiki/Documentation

关于clojurescript - 有没有办法在不使用匿名函数的情况下在 Om 中创建一个 onClick 处理程序?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27911777/

10-12 04:52