我在我的一个项目中遇到了这种问题。这是我想出的解决方案:
(require '[re-frame.interceptor :refer [->interceptor get-effect get-coeffect assoc-coeffect assoc-effect]])
(defn path-by [path-key event->path]
(->interceptor
:id ::path-by
:before
(fn
[context]
(let [original-db (get-coeffect context :db)
event (get-coeffect context :event)
path (or (event->path event)
(path-key original-db))
original-db' (assoc original-db path-key path)]
(assert (some? path)
"Cannon get path neither from event->path nor from db.")
(-> context
(assoc ::original-db original-db')
(assoc-coeffect :db (get-in original-db' path)))))
:after
(fn [context]
(let [original-db (::original-db context)
path (path-key original-db)
context' (-> (dissoc context ::original-db)
(assoc-coeffect :db original-db))
db (get-effect context :db ::not-found)]
(if (= db ::not-found)
context'
(->> (assoc-in original-db path db)
(assoc-effect context' :db)))))))
其中大部分是从 re-frame 的原始路径拦截器中借来的。
这是使用示例:
(rf/reg-event-fx ::taks-viewed
(path-by
::current-task
(fn [[_ id]] id))
(fn [{:keys [db]} [_ id]]
{:db (assoc db :loading true)
:http {...}}))