我想为Om组件创建一个单击处理程序函数。我发现的docs和Stack溢出示例总是声明如下的匿名函数
(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区域之外声明单击函数比较干净,这是在常规反应中通常所做的事情。在组件内部的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"))))如果可能的话,我希望避免在组件之外定义单独的函数。
发布于 2015-01-13 04:48:41
您的问题是明智的,它是关于处理范围的数据。
这是可能的,但这种方法的问题是,在大多数情况下,您需要来自外部代码块的本地范围数据(在您的例子中,它是一个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协议一样。请参考Om生命周期协议以获得正确的使用。
发布于 2015-01-13 02:58:13
根据您的需求,您应该将函数定义移出组件。
然后,您应该能够将函数的名称传递给事件侦听器:
(defn foo [] (println "foo"))
(defn my-component [text owner]
(reify
om/IRender
(render [_]
(dom/button
#js { :onClick foo }
"Click Here"))))https://stackoverflow.com/questions/27911777
复制相似问题