(defmulti pages :name)
(defn main-panel []
(let [current-route (re-frame/subscribe [:current-route])]
(fn []
;...
(pages @current-route))))
然后我有以下方法:
(defmethod layout/pages :register [_] [register-page])
其中register-page
函数将生成实际视图:
(defn register-page []
(let [registration-form (re-frame/subscribe [:registration-form])]
(fn []
[:div
[:h1 "Register"]
;...
])))
我尝试更改我的应用程序,使方法直接生成页面,例如:
(defmethod layout/pages :register [_]
(let [registration-form (re-frame/subscribe [:registration-form])]
(fn []
[:div
[:h1 "Register"]
;...
])))
这导致没有页面被呈现。在我的主面板中,我将调用pages
的方式更改为方括号,以便Reagent可以对其进行可见性处理:
(defn main-panel []
(let [current-route (re-frame/subscribe [:current-route])]
(fn []
;...
[pages @current-route])))
这导致第一个访问的页面可以工作,但之后点击链接(会导致当前路由更改)没有效果。
在包含init函数的文件中,所有定义单个方法的命名空间都是必需的,而我可以选择任何一个单独的页面并将其显示出来,这证明了代码正在加载(然后切换到另一页不起作用):
https://github.com/carouselapps/ninjatools/blob/master/src/cljs/ninjatools/core.cljs#L8-L12
为了调试究竟发生了什么,我定义了两个路由::about
和:about2
,一个作为函数,一个作为方法:
(defn about-page []
(fn []
[:div "This is the About Page."]))
(defmethod layout/pages :about [_]
[about-page])
(defmethod layout/pages :about2 [_]
(fn []
[:div "This is the About 2 Page."]))
并使布局打印调用pages
函数的结果(当然必须使用显式调用而不是方括号)。包装后的函数,也就是起作用的函数,返回:
[#object[ninjatools$pages$about_page "function ninjatools$pages$about_page(){
return (function (){
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),"This is the About Page."], null);
});
}"]]
当该方法返回时:
#object[Function "function (){
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),"This is the About 2 Page."], null);
}"]
如果我把方法改成:
(defmethod layout/pages :about2 [_]
[(fn []
[:div "This is the About 2 Page."])])
也就是说,将函数返回到一个向量中,然后它开始工作。如果我对被包装的函数进行相反的更改,它将以与该方法相同的方式失败:
(defn about-page []
(fn []
[:div "This is the About Page."]))
(defmethod layout/pages :about [_]
about-page)
Reagent的语法是[function]
,这有点合理,但它本应自动调用函数。
我还开始向浏览器输出@current-route
:
[:main.container
[alerts/view]
[pages @current-route]
[:div (pr-str @current-route)]]
我已验证@current-route
正在被正确修改并更新输出,只是没有更新[pages @current-route]
。
我的应用程序的完整源代码可以在此处找到:https://github.com/carouselapps/ninjatools/tree/multi-methods
defmethod
?因为如果你不显式地要求这些命名空间,你的方法就不会被添加到多方法中。 - skrat