简体   繁体   English

有没有办法在不使用匿名函数的情况下在Om中创建onClick处理程序?

[英]Is there any way to make an onClick handler in Om without using anonymous function?

I want to make a click handler function for an Om component. 我想为Om组件创建一个单击处理函数。 The docs and Stack Overflow examples I've found always declare anonymous functions like this 我发现的docs和Stack Overflow示例总是声明这样的匿名函数

(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!"))))))

I think it's cleaner to declare click functions outside the jsx/template area, within the component, the way it's commonly done in regular React. 我认为在组件内部声明jsx / template区域外的单击函数比常规React中通常做的方式更清晰。 Is there a way do this in Om within the component? 在组件中有没有办法在Om中执行此操作? I tried this, but it doesn't work because onClick is undefined: 我试过这个,但它不起作用因为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"))))

I'd like to avoid defining a separate function outside the component if it's possible. 如果可能的话,我想避免在组件外部定义单独的函数。

Your question is sensible and it's about handling scope of data. 你的问题是明智的,它是关于处理数据的范围。

It is possible but the problem with this approach in most cases you will need local scope data from the outside code block (in your case, it's an Om component). 这是可能的,但在大多数情况下,这种方法的问题是你需要来自外部代码块的本地范围数据(在你的情况下,它是一个Om组件)。

I would explain in code. 我会在代码中解释。 Let's say you want to move handler function out: 假设你要移出处理函数:

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

You'll end up with this which is way longer: 你最终会得到这个更长的时间:

(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))))

in case you just want to move around inside the component definition: 如果您只想在组件定义内移动:

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

Please note: to keep event handler work, ensure your non-anonymous function (created with defn or let) is the same as the anonymous form, especially argument list. 请注意:为了使事件处理程序工作,请确保您的非匿名函数(使用defn或let创建)与匿名表单相同,尤其是参数列表。

onClick is undefined because you use it as if it's an Om protocol. onClick未定义,因为您使用它就好像它是一个Om协议。 Please consult Om lifecycle protocols for correct usage. 有关正确使用,请参阅Om生命周期协议。

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

Per your requirements, you should move the function definition out of the component. 根据您的要求,您应该将功能定义移出组件。

You should then be able to pass the function's name to the event listener: 然后,您应该能够将函数的名称传递给事件侦听器:

(defn foo [] (println "foo"))

(defn my-component [text owner]
  (reify
    om/IRender
    (render [_]
        (dom/button
          #js { :onClick foo }
          "Click Here"))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM