使用defmulti和defn作为om / build-all的函数有什么区别?

时间:2015-01-20 12:56:05

标签: clojure clojurescript om

  • om“0.8.0”

我最近通过使用om存储库的om代码开始学习examples。现在,我正在检查multi示例,我可以理解该程序的行为。

点击“+”按钮后,

  • 首先,打印“Even(或Odd)小部件卸载”。
  • 接下来,打印“奇数(或偶数)小部件安装”。

但是当我添加以下代码时 (只需将偶数奇怪的小部件defmulti代码更改为defn代码)

(defn test-widget
  [props owner]
  (reify
    om/IWillMount
    (will-mount [_]
      (println "Test widget mounting"))
    om/IWillUnmount
    (will-unmount [_]
      (println "Test widget unmounting"))
    om/IRender
    (render [_]
      (dom/div nil
        (dom/h2 nil (str "Test Widget: " (:my-number props)))
        (dom/p nil (:text props))
        (dom/button
          #js {:onClick #(om/transact! props :my-number inc)}
          "+")))))

并尝试使用此功能代替test-widget,因此,没有打印消息......

那么defmulti和defn在这种情况下有什么区别? 这个错误还是正确的行为?

提前致谢。

1 个答案:

答案 0 :(得分:2)

协议方法om/IWillMountom/IWillUnmount仅在安装/卸载组件时调用一次。它不会在每个渲染上调用,因此当您单击' +'时不会生成日志消息。按钮,如果它不会导致组件被装入/卸载。多方法的使用对此行为没有影响。

您在使用多方法版本时看到重复日志语句的原因是每次点击都会返回不同的组件,因此每次点击“+”时都会安装/卸载组件,使用普通功能时,每次点击“+”时都会安装一个组件并保持安装状态。

您生成的日志消息将显示在浏览器的开发人员控制台中,用于普通函数和多方法版本,但仅限于组件安装/卸载而不是每次渲染时。

点击' +'按钮将在普通功能方案中触发现有已安装组件中的重新渲染。如果要登录组件的每个渲染,则需要执行以下操作:

(defn test-widget
  [props owner]
  (reify
    om/IWillMount
    (will-mount [_]
      (println "Test widget mounting"))
    om/IWillUnmount
    (will-unmount [_]
      (println "Test widget unmounting"))
    om/IRender
    (render [_]
      (.log js/console "Rendering test widget!")
      (dom/div nil
               (dom/h2 nil (str "Test Widget: " (:my-number props)))
               (dom/p nil (:text props))
               (dom/button
                #js {:onClick #(om/transact! props :my-number inc)}
                "+")))))

(defn app [props owner]
  (reify
    om/IRender
    (render [_]
      (apply dom/div nil
        (om/build-all test-widget (:widgets props))))))