mirror of
https://github.com/metosin/reitit.git
synced 2025-12-16 16:01:11 +00:00
Add re-frame example
This commit is contained in:
parent
215884abe3
commit
bcd4aa33ca
11 changed files with 266 additions and 0 deletions
26
examples/frontend-re-frame/README.md
Normal file
26
examples/frontend-re-frame/README.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# frontend-re-frame
|
||||
|
||||
A [re-frame](https://github.com/Day8/re-frame) application designed to ... well, that part is up to you.
|
||||
|
||||
## Development Mode
|
||||
|
||||
### Run application:
|
||||
|
||||
```
|
||||
lein clean
|
||||
lein figwheel dev
|
||||
```
|
||||
|
||||
Figwheel will automatically push cljs changes to the browser.
|
||||
|
||||
Wait a bit, then browse to [http://localhost:3449](http://localhost:3449).
|
||||
|
||||
## Production Build
|
||||
|
||||
|
||||
To compile clojurescript to javascript:
|
||||
|
||||
```
|
||||
lein clean
|
||||
lein cljsbuild once min
|
||||
```
|
||||
52
examples/frontend-re-frame/project.clj
Normal file
52
examples/frontend-re-frame/project.clj
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
(defproject frontend-re-frame "0.1.0-SNAPSHOT"
|
||||
:dependencies [[org.clojure/clojure "1.10.0"]
|
||||
[org.clojure/clojurescript "1.10.520"]
|
||||
[metosin/reitit "0.3.1"]
|
||||
[reagent "0.8.1"]
|
||||
[re-frame "0.10.6"]]
|
||||
|
||||
:plugins [[lein-cljsbuild "1.1.7"]
|
||||
[lein-figwheel "0.5.18"]
|
||||
[cider/cider-nrepl "0.21.1"]]
|
||||
|
||||
:repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}
|
||||
:min-lein-version "2.5.3"
|
||||
:source-paths ["src/clj" "src/cljs"]
|
||||
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"]
|
||||
:figwheel {:css-dirs ["resources/public/css"]}
|
||||
|
||||
:profiles
|
||||
{:dev
|
||||
{:dependencies
|
||||
[[binaryage/devtools "0.9.10"]
|
||||
[cider/piggieback "0.4.0"]
|
||||
[figwheel-sidecar "0.5.18"]]
|
||||
|
||||
:plugins [[lein-figwheel "0.5.18"]]}
|
||||
:prod {}}
|
||||
|
||||
:cljsbuild
|
||||
{:builds
|
||||
[{:id "dev"
|
||||
:source-paths ["src/cljs"]
|
||||
:figwheel {:on-jsload "frontend-re-frame.core/mount-root"}
|
||||
:compiler {:main frontend-re-frame.core
|
||||
:output-to "resources/public/js/compiled/app.js"
|
||||
:output-dir "resources/public/js/compiled/out"
|
||||
:asset-path "js/compiled/out"
|
||||
:source-map-timestamp true
|
||||
:preloads [devtools.preload]
|
||||
:external-config {:devtools/config {:features-to-install :all}}
|
||||
}}
|
||||
|
||||
{:id "min"
|
||||
:source-paths ["src/cljs"]
|
||||
:compiler {:main frontend-re-frame.core
|
||||
:output-to "resources/public/js/compiled/app.js"
|
||||
:optimizations :advanced
|
||||
:closure-defines {goog.DEBUG false}
|
||||
:pretty-print false}}
|
||||
|
||||
|
||||
]}
|
||||
)
|
||||
13
examples/frontend-re-frame/resources/public/index.html
Normal file
13
examples/frontend-re-frame/resources/public/index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="js/compiled/app.js"></script>
|
||||
<script>frontend_re_frame.core.init();</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
(ns frontend-re-frame.core)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(ns frontend-re-frame.config)
|
||||
|
||||
(def debug?
|
||||
^boolean goog.DEBUG)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
(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]))
|
||||
|
||||
(defn dev-setup []
|
||||
(when config/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]
|
||||
(.getElementById js/document "app")))
|
||||
|
||||
(defn ^:export init []
|
||||
(re-frame/dispatch-sync [::events/initialize-db])
|
||||
(dev-setup)
|
||||
(mount-root))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(ns frontend-re-frame.db)
|
||||
|
||||
(def default-db
|
||||
{})
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
(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)))
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
(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}))
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(ns frontend-re-frame.subs
|
||||
(:require
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::current-route
|
||||
(fn [db]
|
||||
(:current-route db)))
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
(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]])]))
|
||||
Loading…
Reference in a new issue