3

从这两个负责获取当前用户信息的处理程序开始:

(re-frame/register-handler
  :got-user
  (fn [db [_ user]]
    (assoc db :user user)))

(re-frame/register-handler
  :get-user
  (fn [db [_]]
    (ajax/GET "/user" 
       {:handler #(re-frame/dispatch [:got-user %1])})
    db))

在一个页面中,我想显示朋友列表,但问题是它取决于首先获取的用户:

(re-frame/register-handler
  :get-friends
  (fn [db [_]]
    (when (nil? (:user db))
      (re-frame/dispatch [:get-user]))
    ; Here's the problem, as I need to way for get-users and got-users to run.
    (ajax/GET (str "/users/" (get-in db [:user :id])) 
       {:handler #(re-frame/dispatch [:got-friends %1])})
    db))

我应该如何构造这段代码?

4

2 回答 2

2

首先,该文档特别警告不要创建具有副作用的处理程序(即从事件处理程序分派事件)。其次,不要尝试重用事件处理程序,而是将可重用部分重构为辅助函数。使用re-frame-http-fx,我会写这样的东西:

(reg-event-fx
  :get-friends
  [trim-v]
  (fn
    [{db :db} [_]]
    {:http-xhrio  (if (:user db)
                  {:method          :get
                  :uri             (str "/users/" (get-in db [:user :id])) 
                  :on-success      [:got-friends]
                  :on-failure      [:get-friends-load-failed]}

                  {:method          :get
                  :uri             "/user" 
                  :on-success      [:get-friends-for-user]
                  :on-failure      [:get-friends-user-load-failed]})
     :db         db}
    ))

:get-friends-for-user 将首先存储检索到的用户并开始获取朋友。

于 2017-11-03T07:10:08.423 回答
1

关于解决 CPU hog 问题的文章中获得一些灵感,我让 get-friends 在用户为 nil 时调用自己,但为了避免向服务器发送许多请求,它还添加了一个关于被请求用户的标志:

(re-frame/register-handler
  :get-friends
  (fn [db [_ user-requested]]
    (if-let [user (:user db)]
      (ajax/GET (str "/users/" (get-in db [:user :id]))
                {:handler #(re-frame/dispatch [:got-friends %1])})
      (do
        (when (not user-requested)
          (re-frame/dispatch [:get-user]))
        (re-frame/dispatch [:get-friends true])))
    db))

它可以工作,但在本地机器上它设法调用自己 9 次左右,直到 got-user 设置用户。不确定这是否会成为问题,如果存在其他解决方案,我愿意接受。

于 2015-08-13T13:34:28.157 回答