在我正在构建的小应用程序中使用Reagent和Re-frame我正在使用多方法来调度哪个页面应该根据app状态中的值显示:
(defmulti pages :name)
(defn main-panel []
(let [current-route (re-frame/subscribe [:current-route])]
(fn []
;...
(pages @current-route))))
Run Code Online (Sandbox Code Playgroud)
然后我有方法,如:
(defmethod layout/pages :register [_] [register-page])
Run Code Online (Sandbox Code Playgroud)
在register-page功能会产生实际的观点:
(defn register-page []
(let [registration-form (re-frame/subscribe [:registration-form])]
(fn []
[:div
[:h1 "Register"]
;...
])))
Run Code Online (Sandbox Code Playgroud)
我尝试更改我的应用程序,以便方法直接生成页面,如:
(defmethod layout/pages :register [_]
(let [registration-form (re-frame/subscribe [:registration-form])]
(fn []
[:div
[:h1 "Register"]
;...
])))
Run Code Online (Sandbox Code Playgroud)
这导致没有任何页面被渲染.在我的主面板中,我将调用更改pages为方括号,以便Reagent可以看到它:
(defn main-panel []
(let [current-route (re-frame/subscribe [:current-route])]
(fn []
;...
[pages @current-route])))
Run Code Online (Sandbox Code Playgroud)
这导致第一个访问过的页面工作,但在此之后,单击链接(导致当前路由更改)无效.
在首先加载的文件中需要定义各个方法的所有命名空间,其中包含init函数,以及我可以选择任何单个页面并显示它的事实证明代码正在加载(然后,切换到另一个页面没有工作):
https://github.com/carouselapps/ninjatools/blob/master/src/cljs/ninjatools/core.cljs#L8-L12
在努力调试这是怎么回事,我定义了两个路线,:about以及 …
我正在构建一个带有重新框架的应用程序,我想知道试剂形式是否意味着是否与重新框架一起使用,因为试剂形式带来了自己的处理状态,这与重新框架不同.
考虑以下使用幽灵,试剂和重构框架的clojurescript代码,外部React.js网格组件用作视图组件.
在db.cls中:
(def default-db
{:cats [{:id 0 :data {:text "ROOT" :test 17} :prev nil :par nil}
{:id 1 :data {:text "Objects" :test 27} :prev nil :par 0}
{:id 2 :data {:text "Version" :test 37} :prev nil :par 1}
{:id 3 :data {:text "X1" :test 47} :prev nil :par 2}]})
Run Code Online (Sandbox Code Playgroud)
在subs.cls中
(register-sub
:cats
(fn [db]
(reaction
(select [ALL :data] (t/tree-visitor (get @db :cats))))))
Run Code Online (Sandbox Code Playgroud)
选择结果:
[{:text "ROOT", :test 17}
{:text "Objects", :test 27}
{:text "Version", :test 37}
{:text "X1", :test 47}]
Run Code Online (Sandbox Code Playgroud)
在views.cls中 …
我有几个选择,但两者看起来都有点滞后,我认为应该有更好的选择.我只是希望能够创建表单,甚至动态创建表单(例如,从我的应用程序中向表单添加行),并具有试剂/重新框架/反应适当的访问不同输入的值.
不确定这些中的任何一个是否是最佳替代方案,因为它们都在每次运行之后运行:on-change...
选项#1 - 更新:on-change到全局原子
[:input {:value @new-job-form
:on-change #(dispatch [:new-job-form (-> % .-target .-value)])}]
(reg-event-db
:new-job-form
(fn [db [_ v]]
(assoc db :new-job-form v)))
Run Code Online (Sandbox Code Playgroud)
选项#2 - 更新一些只调度到全局原子的本地状态:on-blur
(defn text-input
"adapted from:
https://yogthos.net/posts/2016-09-25-ReagentComponents.html
The big idea is this holds local state, and pushes it to the global
state only when necessary"
[{:keys [sub-path disp]}]
(r/with-let [value (r/atom nil)
focused? (r/atom false)]
[:div
[:input
{:type :text
:on-focus #(do (reset! value @(subscribe sub-path))
(reset! focused? true))
:on-blur …Run Code Online (Sandbox Code Playgroud) 我尝试在Google Chart中调整此示例.到re-frame框架,reagent.我想基于订阅创建一个实时图表.我用一个简单的计数器= + - 1测试.
我收到了错误: Assert failed: Render must be a function, not nil
(ifn? render-fun).
(defn draw-demo-chart
[d]
(let [[columns vectors options chart] (r/children d)
data (new js/google.visualization.DataTable)]
(doall ;gotta keep the doall on maps. lazy sequence...
(map (fn [[type name]]
(.addColumn data type name)) columns))
(.addRows data vectors)
(.draw chart data options)
(.load js/google "visualization" "1" (clj->js {:packages ["corechart" "orgchart" "calendar" "map" "geochart"]}))
(.setOnLoadCallback js/google draw-demo-chart)
))
(defn draw-demo-chart-container
[] …Run Code Online (Sandbox Code Playgroud) 我正在玩这个re-frame框架.
在下面的代码中,当用户输入以下内容时,我无法更新输入值:
(defn measurement-input [{:keys [amount unit path]}]
(let [amt (atom amount)]
(fn []
[:div
[:input {:type "text"
:value @amt
:on-change #(reset! amt (-> % .-target .-value))}]
[:input {:type "button"
:value unit}]])))
Run Code Online (Sandbox Code Playgroud)
输入值将不会改变,直到,直到我换:value到:defaultValue.我很确定上面的例子很接近镜像Reagent的输入示例.
在下面的代码中,我试图在用户更新输入值时做两件事.我正在尝试reset!输入的值以及dispatch事件处理程序的值.我在调用中已经完成了这两个函数调用do.
另外值得注意的是,在下面的代码中,用户能够更新文本字段中的值.
(defn measurement-input [{:keys [amount unit path]}]
(let [amt (atom amount)]
(fn []
[:div
[:input {:type "text"
:value @amt
:on-change (do #(reset! amt (-> % .-target .-value))
(re-frame/dispatch [:update-value @amt]))}]
[:input {:type …Run Code Online (Sandbox Code Playgroud) 我正在重新构建默认模板之上构建应用程序.
我有以下秘书路线:
(defroute "/users/:id" []
(re-frame/dispatch [:set-active-panel :user-panel])
Run Code Online (Sandbox Code Playgroud)
我想id从我的试剂组件中的URL 访问参数.我发现实现它的唯一方法就是设置它db.就像是:
(defroute "/users/:id" [id]
(re-frame/dispatch [:set-user-id id])
(re-frame/dispatch [:set-active-panel :user-panel])
Run Code Online (Sandbox Code Playgroud)
这肯定会污染我的数据库,这种方法对我来说似乎很奇怪,因为我曾经在反应中写这样的东西(使用react-router):
<Route path="/user/:id" component={MyComponent}>
// object with params automatically attached as props to MyComponent
Run Code Online (Sandbox Code Playgroud)
那么将秘书URL参数广播到试剂组件的正确方法是什么?
UPD:在评论中有一个链接到github讨论这个问题.Ones指的是将URL params设置为db作为正确的方法.无论如何,我真的不喜欢它.它会导致更多的复杂性(设置params,订阅它们,取消设置).而且我不喜欢将URL params视为app状态.有什么黑客或其他什么?
我重新构建 views.cljs 有:
(re-frame/dispatch [::re-graph/init
{:http-url "https://api.spacex.land/graphql"
:ws-url nil
:http-parameters {:with-credentials? false}}])
(re-frame/dispatch [::re-graph/query
"{ launches { id, mission_name } }" ;; your graphql query
[::update-data]])
Run Code Online (Sandbox Code Playgroud)
我的 events.cljs 有:
(re-frame/reg-event-db
::update-data
(fn [db [_ {:keys [data errors] :as payload}]]
(-> db
(assoc :errors errors)
(assoc :data data))))
Run Code Online (Sandbox Code Playgroud)
但我不断收到此错误:
core.cljs:3919 re-frame: no :event handler registers for: undefined
某些事件不会导致app-db变化.他们只更改dom,例如:init自定义滚动,获取所选文本等.我应该如何在重新框架中处理它们,因为事件处理程序需要返回一个新的app-db?我通过返回现有的数据库来解决这个问题,但这似乎不对.有没有更好的方法呢?我的一些处理程序看起来像这样:
(re-frame/reg-event-db
:init-link-viewer
(fn [db [_ highlights]]
(utils/load-highlights highlights)
(utils/init-selection)
db))
Run Code Online (Sandbox Code Playgroud) 以下方法中最好的是什么?
外部订阅,早期deref
(defn component [msg]
[:p msg]))
(let [msg (rf/subscribe [:msg])]
[component @msg]
Run Code Online (Sandbox Code Playgroud)
外部订阅,晚期deref
(defn component [msg]
[:p @msg]))
(let [msg (rf/subscribe [:msg])]
[component msg]
Run Code Online (Sandbox Code Playgroud)
内部订阅,早期deref
(defn component []
(let [msg @(rf/subscribe [:msg])]
[:p msg])))
Run Code Online (Sandbox Code Playgroud)
内部订阅,迟到deref
(defn component []
(let [msg (rf/subscribe [:msg])]
[:p @msg])))
Run Code Online (Sandbox Code Playgroud)
当我使用外部订阅保持内部组件纯粹时,我最终可能会有许多参数需要通过经常无关的父级的深层嵌套结构传递.这很容易变得一团糟.
当我在内部组件内部订阅时,它变得不纯净,失去了易测试性.
另外,我想知道早期和晚期解除引用之间是否存在重要差异,除了reagent/atom在测试后者时我必须通过.