Liking cljdoc? Tell your friends :D

district-ui-router

CircleCI Clojars Project

Clojurescript re-mount module, that provides routing functionality for UI. This module currently utilises a forked bide routing library. It also provides 2 reagent components helpful for switching pages in UI based on currently active page.

Installation

Add [district0x/district-ui-router "VERSION"] into your project.clj

Include [district.ui.router] in your CLJS file, where you use mount/start

API Overview

Warning: district0x modules are still in early stages, therefore API can change in a future.

district.ui.router

This namespace contains router mount module.

You can pass following args to initiate this module:

  • :routes Routes as you'd pass them into bide library
  • :default-route Default route, passed as :default into bide library.
  • :html5? Pass true if you want to use HTML5 history. This option overrides :html5-hosts.
  • :html5-hosts Collection of hostnames for which HTML5 history should be used. You can also pass string of comma separated
  • :scroll-top? When true will scroll window to top after navigation hostnames instead of collection. This is useful for defining hostnames in project.clj via :closure-defines.
  (ns my-district.core
    (:require [mount.core :as mount]
              [district.ui.router]))

  (-> (mount/with-args
        {:router {:routes [["/a" :route/a]
                           ["/b/:b" :route/b]]
                  :default-route :route/a
                  :html5-hosts ["localhost" "mydomain.com"]}})
    (mount/start))

district.ui.router.subs

re-frame subscriptions provided by this module:

::active-page

Returns active page. A map containing :name :params :query.

::active-page-name

Returns route name of active page.

::active-page-params

Returns params of active page.

::active-page-query

Returns query of active page.

::resolve

Works as bide's resolve, but you don't need to pass router.

::match

Works as bide's match, but you don't need to pass router.

::bide-router

Return's bide's router.

::html5?

True if using HTML5 History.

district.ui.router.events

re-frame events provided by this module:

::active-page-changed

Event fired when active page has been changed. Use this event to hook into event flow.

::watch-active-page

Event to call ::watch-active-page effect.

::unwatch-active-page

Event to call ::unwatch-active-page effect.

::navigate

Event to call ::navigate effect.

::replace

Event to call ::replace effect.

district.ui.router.effects

re-frame effects provided by this module

::watch-active-page

This is special type of effect useful for hooking into active-page-changed event. Works similarly as re-frame-forward-events-fx, but instead of dispatching being based on events, it is based on route name, params and query. This is useful when, for example, your module needs to load data when user visits certain page.

As a param you pass collection of maps containing following keys:

  • :id ID of watcher, so you can later unwatch using this ID
  • :name Route name dispatching will be based on. You can pass also collection of routes or a predicate function.
  • :params Route params dispatching will be based on. You can also pass predicate function.
  • :query Route query dispatching will be based on. You can also pass predicate function.
  • :dispatch Dispatch fired when certain name/params/query is hit. Fired event will get name, params, query as last 3 args.
  • :dispatch-n Dispatches fired when certain name/params/query is hit.

You can do dispatching based on either name, params or query, or any combination of two or three of them.

(ns my.district
  (:require
    [district.ui.router.effects :as router-effects]
    [re-frame.core :refer [reg-event-fx]]))


(reg-event-fx
  ::my-event
  (fn []
    ;; When :route/b page is visited ::some-event will be fired
    {::router-effects/watch-active-page [{:id :watcher1
                                          :name :route/b
                                          :dispatch [::some-event]}]}))

(reg-event-fx
  ::my-event
  (fn []
    ;; When :route/c page with {:a 1} params is visited ::some-event will be fired
    {::router-effects/watch-active-page [{:id :watcher1
                                          :name :route/c
                                          :params {:a 1}
                                          :dispatch [::some-event]}]}))

(reg-event-fx
  ::my-event
  (fn []
    ;; When any page with {:some-param "abc"} query is visited ::some-event will be fired
    {::router-effects/watch-active-page [{:id :watcher1
                                          :query {:some-param "abc"}
                                          :dispatch [::some-event]}]}))

::unwatch-active-page

Unwatches previously set watcher based on :id.

(reg-event-fx
  ::my-event
  (fn []
    {::router-effects/unwatch-active-page [{:id :watcher1}]}))

::navigate

Reframe effect to call bide's navigate! function.

::replace

Reframe effect to call bide's replace! function.

district.ui.router.queries

DB queries provided by this module: You should use them in your events, instead of trying to get this module's data directly with get-in into re-frame db.

active-page [db]

Works the same way as sub ::active-page

active-page-name [db]

Works the same way as sub ::active-page-name

active-page-params [db]

Works the same way as sub ::active-page-params

active-page-query [db]

Works the same way as sub ::active-page-query

assoc-active-page [db active-page]

Associates new active-page and returns new re-frame db.

resolve [db & args]

Works the same way as sub ::resolve

match [db & args]

Works the same way as sub ::match

bide-router [db]

Works the same way as sub ::bide-router

html5? [db]

Works the same way as sub ::html5?

assoc-bide-router [db bide-router]

Associates new bide router and returns new re-frame db.

assoc-html5 [db html5?]

Associates whether the module is using html5 history or not.

district.ui.router.utils

Util functions provided by this module:

resolve [name & [params query]]

Serves as a wrapper for instantly derefed sub ::resolve.

match [path]

Serves as a wrapper for instantly derefed sub ::match.

(ns my-district.core
    (:require [mount.core :as mount]
              [district.ui.router]
              [district.ui.router.utils :as utils]))

  (-> (mount/with-args
        {:router {:routes [["/a" :route/a]
                           ["/b/:b" :route/b]]
                  :default-route :route/a}})
    (mount/start))

(utils/resolve :route/a)
;; => "/a"

(utils/resolve :route/b {:b "abc"} {:c "xyz"})
;; => "/b/abc?c=xyz"

(utils/match "/b/abc?c=xyz")
;; => [:route/b {:b "abc"} {:c "xyz"}]

district.ui.component.page

Multimethod to define pages upon. district.ui.component.router component will then route those pages according to active-page.

(ns my-district.core
  (:require
    [district.ui.component.page :refer [page]]))

(defmethod page :route/home []
  [:div "Welcome to Home Page"])

district.ui.component.router

Components that switches pages (as defined via district.ui.component.page) based on current active-page.

(ns my-district.core
  (:require
    [reagent.core :as r]
    [mount.core :as mount]
    [district.ui.router]
    [district.ui.component.page :refer [page]]
    [district.ui.component.router :refer [router]]))

  (-> (mount/with-args
        {:router {:routes [["/" :route/home]
                           ["/user" :route/user]]
                  :default-route :route/home}})
    (mount/start))

(defmethod page :route/home []
  [:div "Welcome to Home Page"])

(defmethod page :route/user []
  [:div "Welcome to User Page"])

(r/render [router] (.getElementById js/document "app"))

Development

lein deps
# To run tests and rerun on changes
lein doo chrome tests

Can you improve this documentation? These fine people already did:
madvas, Benjamin Zaporzan, Juan Monetta & fbielejec
Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close