使用宏来生成Om组件

时间:2015-06-03 02:31:13

标签: clojure clojurescript om

我正在尝试使用宏来生成一系列类似的Om组件(例如,包含公共样板和动态“body”的模态元素)。

我在下面的解决方案主要是工作。一个例外是访问表单的owner事件处理程序中的相应on-submit

;; macros.clj
(defmacro build-modal
  ([disp-name body]
  `(fn [_# owner#]
    (reify
      om.core/IRender
      (~'render [_#]
                (dom/div {:class "login-view-modal"}
                         (dom/div {:class "login-view-modal-backsplash"})
                         (dom/div {:class "login-view-modal-content"}
                                  ~@body))))) nil))

;; ui.cljs
(defn login-view-modal []
  (bs-macros/build-modal 
    "login-modal" 
    '(dom/form {:on-submit (fn [event] 
                            (.preventDefault event)
                            (let [username (get-value owner "username")
                                  password (get-value owner "password")
                                  data {:email_address username
                                        :password password}]
                              (handle-login-view-modal-form-submit data)))}
                            ;; elided for brevity
                            (dom/div 
                              (dom/button "LOG IN")))))

(defcomponent home-page-view [app owner]
              (init-state [_] {:text ""})
              (render-state [this state]
                              ;; elided for brevity 
                              (dom/div (login-view-modal))))

模式按预期呈现,但是在提交表单时,我会看到错误:Uncaught TypeError: Cannot read property 'getDOMNode' of undefined,这似乎是因为owner不在范围内。 (注意,当完整构造时,此元素及其事件处理程序按预期运行 - 即不使用宏。)

如何为宏的正文提供适当的owner

1 个答案:

答案 0 :(得分:4)

您需要变量捕获才能工作。而不是通过owner#生成唯一符号的gen-syming,只需内联~'owner,无论您想在哪里引用它。