美文网首页
re-frame,reitit-frontend路由或url里传

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

作者: 小马将过河 | 来源:发表于2022-11-04 00:19 被阅读0次

    背景

    最近的项目都用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里传

          本文链接:https://www.haomeiwen.com/subject/vokytdtx.html