re-frame http event-fx, который зависит от данных другого http event-fx

Предположим, мне нужны данные виджета и данные частей виджета. Мне нужно получить данные виджета через http-запрос, чтобы получить его номера частей. Я использую эти номера деталей, чтобы делать больше HTTP-запросов для получения данных о деталях.

Используя https://github.com/Day8/re-frame-http-fx, это будет выглядеть так:

(reg-event-fx
 :foo/get-widget
 (fn [{:keys [db]} [_]]
   {:http-xhrio {:method :get
                 :uri "foobar.com/widget"
                 :format (ajax/transit-request-format)
                 :response-format (ajax/json-response-format)
                 :on-success [:foo/load-widget]
                 :on-failure [:foo/set-error]}}))

(reg-event-fx
 :foo/get-widget-part
 (fn [{:keys [db]} [_ part-number]]
   {:http-xhrio {:method :get
                 :uri (str "foobar.com/part/" part-number)
                 :format (ajax/transit-request-format)
                 :response-format (ajax/json-response-format)
                 :on-success [:foo/load-part]
                 :on-failure [:foo/set-error]}}))

Как мне инициализировать данные о деталях для моей страницы? Самый простой способ, который я могу придумать, - это обернуть get-widget и get-widget-part, написав другой обработчик get-widget-then-widget-parts, выполнив http-запрос для виджета, и в случае успеха возьмите эти данные и извлеките данные частей. Моя проблема в том, что это не очень компонуемо. Мне нужно создать другой обработчик. В то же время я не могу просто (dispatch [:foo/get-widget]) и передать результат в (dispatch [:foo/get-widget-part]) (насколько я знаю).


person deadghost    schedule 17.07.2017    source источник


Ответы (1)


Если я правильно понимаю, ваша цель состоит в том, чтобы создать несколько запросов get-widget-part после того, как get-widget вернет данные виджета с идентификаторами частей. Вы можете написать обработчик событий, который ищет идентификаторы и отправляет несколько событий :foo/get-widget-part.

(reg-event-fx
    :foo/load-widget ;Your :on-success event
    (fn [{:keys [db]} [_ widget-data]]
      (let [ids         (get-part-ids widget-data)
            missing-ids (remove #(get-part-with-id db %) ids)] ;Load only missing parts
        {:db         (set-widget-data db widget-data)
         :dispatch-n (map (fn [id] [:foo/get-widget-part id]) missing-ids)})))

Скорее всего, вы не хотите каждый раз «жадно» доставать детали. Таким образом, вы можете либо А) предоставить отдельный аргумент (например, :fetch-eager) и условно объединить :dispatch-n в зависимости от этого, либо Б) создать отдельные события для ленивой и нетерпеливой выборки (скажем, :foo/get-widget и :foo/get-widget-with-parts). Я бы предпочел последний вариант B, так как его легче использовать, например, когда добавляется выделенная конечная точка API для получения виджета частями.

Вы можете составить создание карты эффекта, возвращаемой обработчиком события. В приведенном выше примере действие отложенной загрузки создаст только эффект :db (например, mk-db-widget-data), в то время как нетерпеливая версия будет состоять из событий :dbupdate и :get-widget-part (например, mk-dispatch-get-widget-parts).

person Toni Vanhala    schedule 18.07.2017