re-frame,reitit-frontend路由或url里传参

背景

最近的项目都用kee-frame,在controller中处理访问时url里的参数,大致会是下面这个样子,

(require '[kee-frame.core :as kf])
(kf/reg-controller
 :broadcast/room-detail-controller
 {:params (fn [route]
            (let [path  (get-in route [:path-params :path])
                  query (get route :query-string)]
              (when (and (= path "/broadcast/room-detail") (re-find #"id=\w+" (or query "")))
                (second (string/split query "=")))))
  :start  (fn [_ id]
            [:broadcast/broadcast-detail-ajax id])
  :stop (fn []
          [::reset])})

但是,今天突然捡起来刚开始学clojure时的一个项目,kee-frame跟现在用法不一样,或者说没有用,用的就是re-frame+reitit routes,突然在发起dispatch时不知道怎么传参,也不知道定义路由时怎么接收了,调研了一下,将结果记录一下,再维护老项目时可以查查。

官方例子

参考了reitit controllers examples的例子,

 ["/:id"
       {:name ::item
        :parameters {:path {:id s/Int}
                     :query {(s/optional-key :foo) s/Keyword}}
        :controllers [{:parameters {:path [:id]}
                       :start (fn [{:keys [path]}]
                                (js/console.log "start" "item controller" (:id path)))
                       :stop (fn [{:keys [path]}]
                               (js/console.log "stop" "item controller" (:id path)))}]}]]]

有点明白怎么回事了。

现状

我们项目的router定义大概是这样的:

(require '[re-frame.core :as rf])
(require '[reitit.core :as re])
(require '[schema.core :as s])

 (def routes
  ["/"
   ;; 进入网页会议和离开网页会议
   ["webjitsi"
    {:name      :routes/webjitsi
     :view      (fn []
                  [meeting-page])
     :link-text "进入网页会议"
     :controllers
     [{:start (fn []
                (info "Entering webjitsi page"))
       :stop  (fn []
                (info "Leaving webjitsi page"))}]}]
    ])

使用的地方

(def router
  (re/router
   routes
   {:data {:coercion rss/coercion}}))

(defn init-routes! []
  (info "initializing routes")
  (rfe/start!
   router
   on-navigate
   {:use-fragment true}))

(已经无从找到为什么是这么写的了,大概2年前的事情了,大概当时re-frame example就这样吧)

更新路由

更新这个路由的结构,使其能接受参数

(def routes
  ["/"
   ;; 进入网页会议和离开网页会议
   ["webjitsi/:course-id/:user-id"
    {:name      :routes/webjitsi
     :view      (fn []
                  [meeting-page])
     :link-text "进入网页会议"
     :parameters    {:path {:course-id string?
                            :user-id string?}
                     :query {(s/optional-key :foo) string?}}
     :controllers
     [{:parameters {:path [:course-id :user-id]
                    :query [:foo]}
       :start (fn [parameters]
                (info "Entering webjitsi page" parameters))
       :stop  (fn []
                (info "Leaving webjitsi page"))}]}]
    ])

调用方式

跳转路由的方式有很多,这里用re-frame提供的navigate,repl里测试

(rf/dispatch [:navigate :routes/webjitsi 
                                   {:course-id "222" :user-id "201"}
                                   {:foo "erere"}])

应该也看出来了,:navigate后的参数依次是【route name】,【path parameters】和【query parameters】,这一点,从reieit文档的Compiling coercers也找到了定义,但是没有找到path和query混用和dispatch的例子(估计是文档没有全部翻一遍)

在repl里调用以后,顺便截了个图,一图剩千言

image.png

你可能感兴趣的:(re-frame,reitit-frontend路由或url里传参)