From 22f38d99924348b54a9746e5d2bc3be02378f5e1 Mon Sep 17 00:00:00 2001 From: Valtteri Harmainen Date: Thu, 25 Apr 2019 10:23:55 +0300 Subject: [PATCH] Revamped re-frame example - Flattened into single file - Changed router to decide which view to render --- .../src/cljs/frontend_re_frame/config.cljs | 4 - .../src/cljs/frontend_re_frame/core.cljs | 151 ++++++++++++++++-- .../src/cljs/frontend_re_frame/db.cljs | 4 - .../src/cljs/frontend_re_frame/events.cljs | 20 --- .../src/cljs/frontend_re_frame/routes.cljs | 67 -------- .../src/cljs/frontend_re_frame/subs.cljs | 8 - .../src/cljs/frontend_re_frame/views.cljs | 47 ------ 7 files changed, 142 insertions(+), 159 deletions(-) delete mode 100644 examples/frontend-re-frame/src/cljs/frontend_re_frame/config.cljs delete mode 100644 examples/frontend-re-frame/src/cljs/frontend_re_frame/db.cljs delete mode 100644 examples/frontend-re-frame/src/cljs/frontend_re_frame/events.cljs delete mode 100644 examples/frontend-re-frame/src/cljs/frontend_re_frame/routes.cljs delete mode 100644 examples/frontend-re-frame/src/cljs/frontend_re_frame/subs.cljs delete mode 100644 examples/frontend-re-frame/src/cljs/frontend_re_frame/views.cljs diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/config.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/config.cljs deleted file mode 100644 index c017bfb3..00000000 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/config.cljs +++ /dev/null @@ -1,4 +0,0 @@ -(ns frontend-re-frame.config) - -(def debug? - ^boolean goog.DEBUG) diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/core.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/core.cljs index f4d8c2f0..7999ba5f 100644 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/core.cljs +++ b/examples/frontend-re-frame/src/cljs/frontend_re_frame/core.cljs @@ -1,24 +1,157 @@ (ns frontend-re-frame.core (:require - [reagent.core :as reagent] [re-frame.core :as re-frame] - [frontend-re-frame.events :as events] - [frontend-re-frame.views :as views] - [frontend-re-frame.config :as config] - [frontend-re-frame.routes :as routes])) + [reagent.core :as reagent] + [reitit.core :as r] + [reitit.coercion :as rc] + [reitit.coercion.spec :as rss] + [reitit.frontend :as rf] + [reitit.frontend.controllers :as rfc] + [reitit.frontend.easy :as rfe])) + +;;; Events ;;; + +(re-frame/reg-event-db + ::initialize-db + (fn [_ _] + {:current-route nil})) + +(re-frame/reg-event-fx + ::navigate + (fn [db [_ route]] + ;; See `navigate` effect in routes.cljs + {::navigate! route})) + +(re-frame/reg-event-db + ::navigated + (fn [db [_ new-match]] + (assoc db :current-route new-match))) + +;;; Subscriptions ;;; + +(re-frame/reg-sub + ::current-route + (fn [db] + (:current-route db))) + +;;; Views ;;; + +(defn home-page [] + [:div + [:h1 "This is home page"] + [:button + ;; Dispatch navigate event that triggers a (side)effect. + {:on-click #(re-frame/dispatch [::navigate ::sub-page2])} + "Go to sub-page 2"]]) + +(defn sub-page1 [] + [:div + [:h1 "This is sub-page 1"]]) + +(defn sub-page2 [] + [:div + [:h1 "This is sub-page 2"]]) + +;;; Effects ;;; + +;; Triggering navigation from events. +(re-frame/reg-fx + ::navigate! + (fn [k params query] + (rfe/push-state k params query))) + +;;; Routes ;;; + +(defn href + "Return relative url for given route. Url can be used in HTML links." + ([k] + (href k nil nil)) + ([k params] + (href k params nil)) + ([k params query] + (rfe/href k params query))) + +(def routes + ["/" + ["" + {:name ::home + :view home-page + :link-text "Home" + :controllers + [{;; Do whatever initialization needed for home page + ;; I.e (re-frame/dispatch [::events/load-something-with-ajax]) + :start (fn [& params](js/console.log "Entering home page")) + ;; Teardown can be done here. + :stop (fn [& params] (js/console.log "Leaving home page"))}]}] + ["sub-page1" + {:name ::sub-page1 + :view sub-page1 + :link-text "Sub page 1" + :controllers + [{:start (fn [& params] (js/console.log "Entering sub-page 1")) + :stop (fn [& params] (js/console.log "Leaving sub-page 1"))}]}] + ["sub-page2" + {:name ::sub-page2 + :view sub-page2 + :link-text "Sub-page 2" + :controllers + [{:start (fn [& params] (js/console.log "Entering sub-page 2")) + :stop (fn [& params] (js/console.log "Leaving sub-page 2"))}]}]]) + +(defn on-navigate [new-match] + (let [old-match (re-frame/subscribe [::current-route])] + (when new-match + (let [cs (rfc/apply-controllers (:controllers @old-match) new-match) + m (assoc new-match :controllers cs)] + (re-frame/dispatch [::navigated m]))))) + +(def router + (rf/router + routes + {:data {:coercion rss/coercion}})) + +(defn init-routes! [] + (js/console.log "initializing routes") + (rfe/start! + router + on-navigate + {:use-fragment true})) + +(defn nav [{:keys [router current-route]}] + (into + [:ul] + (for [route-name (r/route-names router) + :let [route (r/match-by-name router route-name) + text (-> route :data :link-text)]] + [:li + (when (= route-name (-> current-route :data :name)) + "> ") + ;; Create a normal links that user can click + [:a {:href (href route-name)} text]]))) + +(defn router-component [{:keys [router]}] + (let [current-route @(re-frame/subscribe [::current-route])] + [:div + [nav {:router router :current-route current-route}] + (when current-route + [(-> current-route :data :view)])])) + +;;; Setup ;;; + +(def debug? ^boolean goog.DEBUG) (defn dev-setup [] - (when config/debug? + (when debug? (enable-console-print!) (println "dev mode"))) (defn mount-root [] (re-frame/clear-subscription-cache!) - (routes/init!) ;; Reset routes on figwheel reload - (reagent/render [views/main-panel] + (init-routes!) ;; Reset routes on figwheel reload + (reagent/render [router-component {:router router}] (.getElementById js/document "app"))) (defn ^:export init [] - (re-frame/dispatch-sync [::events/initialize-db]) + (re-frame/dispatch-sync [::initialize-db]) (dev-setup) (mount-root)) diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/db.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/db.cljs deleted file mode 100644 index 147307c0..00000000 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/db.cljs +++ /dev/null @@ -1,4 +0,0 @@ -(ns frontend-re-frame.db) - -(def default-db - {}) diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/events.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/events.cljs deleted file mode 100644 index 4faaca36..00000000 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/events.cljs +++ /dev/null @@ -1,20 +0,0 @@ -(ns frontend-re-frame.events - (:require - [re-frame.core :as re-frame] - [frontend-re-frame.db :as db])) - -(re-frame/reg-event-db - ::initialize-db - (fn [_ _] - db/default-db)) - -(re-frame/reg-event-fx - ::navigate - (fn [db [_ route]] - ;; See `navigate` effect in routes.cljs - {:frontend-re-frame.routes/navigate route})) - -(re-frame/reg-event-db - ::navigated - (fn [db [_ new-match]] - (assoc db :current-route new-match))) diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/routes.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/routes.cljs deleted file mode 100644 index 22fbe6bc..00000000 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/routes.cljs +++ /dev/null @@ -1,67 +0,0 @@ -(ns frontend-re-frame.routes - (:require [frontend-re-frame.events :as events] - [frontend-re-frame.subs :as subs] - [re-frame.core :as re-frame] - [reitit.coercion :as rc] - [reitit.coercion.spec :as rss] - [reitit.frontend :as rf] - [reitit.frontend.controllers :as rfc] - [reitit.frontend.easy :as rfe])) - -;; Effect for triggering navigation from events. -(re-frame/reg-fx - ::navigate - (fn [k params query] - (rfe/push-state k params query))) - -(defn href - "Return relative url for given route. Url can be used in HTML links." - ([k] - (href k nil nil)) - ([k params] - (href k params nil)) - ([k params query] - (rfe/href k params query))) - -(def routes - ["/" - ["" - {:name ::home - :human-name "Home" - :controllers - [{;; Do whatever initialization needed for home page - ;; I.e (re-frame/dispatch [::events/load-something-with-ajax]) - :start (fn [& params](js/console.log "Entering home page")) - ;; Teardown can be done here. - :stop (fn [& params] (js/console.log "Leaving home page"))}]}] - ["sub-page1" - {:name ::sub-page1 - :human-name "Sub page 1" - :controllers - [{:start (fn [& params] (js/console.log "Entering sub-page 1")) - :stop (fn [& params] (js/console.log "Leaving sub-page 1"))}]}] - ["sub-page2" - {:name ::sub-page2 - :human-name "Sub-page 2" - :controllers - [{:start (fn [& params] (js/console.log "Entering sub-page 2")) - :stop (fn [& params] (js/console.log "Leaving sub-page 2"))}]}]]) - -(def router - (rf/router - routes - {:data {:coercion rss/coercion}})) - -(defn on-navigate [new-match] - (let [old-match (re-frame/subscribe [::subs/current-route])] - (when new-match - (let [cs (rfc/apply-controllers (:controllers @old-match) new-match) - m (assoc new-match :controllers cs)] - (re-frame/dispatch [::events/navigated m]))))) - -(defn init! [] - (js/console.log "initializing routes") - (rfe/start! - router - on-navigate - {:use-fragment true})) diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/subs.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/subs.cljs deleted file mode 100644 index aa210a3b..00000000 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/subs.cljs +++ /dev/null @@ -1,8 +0,0 @@ -(ns frontend-re-frame.subs - (:require - [re-frame.core :as re-frame])) - -(re-frame/reg-sub - ::current-route - (fn [db] - (:current-route db))) diff --git a/examples/frontend-re-frame/src/cljs/frontend_re_frame/views.cljs b/examples/frontend-re-frame/src/cljs/frontend_re_frame/views.cljs deleted file mode 100644 index f24b143e..00000000 --- a/examples/frontend-re-frame/src/cljs/frontend_re_frame/views.cljs +++ /dev/null @@ -1,47 +0,0 @@ -(ns frontend-re-frame.views - (:require - [frontend-re-frame.events :as events] - [frontend-re-frame.routes :as routes] - [frontend-re-frame.subs :as subs] - [re-frame.core :as re-frame])) - -(defn home-page [] - [:div - [:h1 "This is home page"] - [:button - ;; Dispatch navigate event that triggers a (side)effect. - {:on-click #(re-frame/dispatch [::events/navigate ::routes/sub-page2])} - "Go to sub-page 2"]]) - -(defn sub-page1 [] - [:div - [:h1 "This is sub-page 1"]]) - -(defn sub-page2 [] - [:div - [:h1 "This is sub-page 2"]]) - -(defn nav [] - (let [current-route (re-frame/subscribe [::subs/current-route])] - [:div - (into - [:ul] - (for [route (->> routes/routes (filter vector?) (map second)) - :let [text (-> route :human-name)]] - [:li - (when (= (:name route) (-> @current-route :data :name)) - "> ") - ;; Create a normal links that user can click - [:a {:href (routes/href (:name route))} text]]))])) - -(defn main-panel [] - (let [current-route (re-frame/subscribe [::subs/current-route])] - [:div - [nav] - (condp = (-> @current-route :data :name) - ::routes/home [home-page] - ::routes/sub-page1 [sub-page1] - ::routes/sub-page2 [sub-page2] - [:div - [:p (str "Unknown page")] - [:pre @current-route]])]))