mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 00:41:12 +00:00
Some documentation for controllers
This commit is contained in:
parent
8cc58df024
commit
adb27f445d
1 changed files with 88 additions and 0 deletions
|
|
@ -7,6 +7,89 @@ Controllers run code when a route is entered and left. This can be useful to:
|
|||
- Load resources
|
||||
- Update application state
|
||||
|
||||
## How controllers work
|
||||
|
||||
A controller consists of three functions:
|
||||
|
||||
* `params` which takes a Match and returns an arbitrary value.
|
||||
* `start` which takes the result of params and whose return value is discarded.
|
||||
* `stop` which takes the result of params and whose return value is discarded.
|
||||
|
||||
When you navigate to a route that has a controller, `params` gets called first
|
||||
and then `start` is called with its return value. When you exit that route,
|
||||
`stop` is called with the return value of `params.`
|
||||
|
||||
If you navigate to the same route with different parameters, `params` gets
|
||||
called again. If the return value changes from the previous return value, `stop`
|
||||
and `start` get called again.
|
||||
|
||||
You can add controllers to a route by adding them to the route data in the
|
||||
`:controllers` vector. For example:
|
||||
|
||||
```clojure
|
||||
["/item/:id"
|
||||
{:controllers [{:params (fn [match] (get-in match [:path-params :id]))
|
||||
:start (fn [item-id] (js/console.log :start item-id))
|
||||
:stop (fn [item-id] (js/console.log :stop item-id))}]}]
|
||||
```
|
||||
|
||||
If you leave out `params`, `start` and `stop` get called with `nil`. You can
|
||||
leave out `start` or `stop` if you do not need both of them.
|
||||
|
||||
## Enabling controllers
|
||||
|
||||
You need to
|
||||
call
|
||||
[`reitit.frontend.controllers/apply-controllers`](https://cljdoc.org/d/metosin/reitit-frontend/CURRENT/api/reitit.frontend.controllers#apply-controllers) whenever
|
||||
the URL changes. You can call it from the `on-navigate` callback of
|
||||
`reitit.frontend.easy`:
|
||||
|
||||
```clojure
|
||||
|
||||
(ns frontend.core
|
||||
(:require [reitit.frontend.easy :as rfe]
|
||||
[reitit.frontend.controllers :as rfc]))
|
||||
|
||||
(defonce match-a (atom nil))
|
||||
|
||||
(def routes
|
||||
["/" ...])
|
||||
|
||||
(defn init! []
|
||||
(rfe/start!
|
||||
routes
|
||||
(fn [new-match]
|
||||
(swap! match-a
|
||||
(fn [old-match]
|
||||
(when new-match
|
||||
(assoc new-match
|
||||
:controllers (rfc/apply-controllers (:controllers old-match) new-match))))))))
|
||||
```
|
||||
|
||||
See also [the full example](https://github.com/metosin/reitit/tree/master/examples/frontend-controllers).
|
||||
|
||||
## Nested controllers
|
||||
|
||||
When you nest routes in the route tree, the controllers get nested as well.
|
||||
Consider this route tree:
|
||||
|
||||
```clojure
|
||||
["/" {:controllers [{:start (fn [_] (js/console.log "root start"))}]}
|
||||
["/item/:id"
|
||||
{:controllers [{:params (fn [match] (get-in match [:path-params :id]))
|
||||
:start (fn [item-id] (js/console.log "item start" item-id))
|
||||
:stop (fn [item-id] (js/console.log "item stop" item-id))}]}]]
|
||||
|
||||
```
|
||||
|
||||
* When you navigate to any route at all, the root controller gets started.
|
||||
* If you navigate to `/item/something`, the root controller gets started first
|
||||
and then the item controller gets started.
|
||||
* If you then navigate from `/item/something` to `/item/something-else`, first
|
||||
the item controller gets stopped with parameter `something` and then it gets
|
||||
started with the parameter `something-else`. The root controller stays on the
|
||||
whole time since its parameters do not change.
|
||||
|
||||
## Authentication
|
||||
|
||||
Controllers can be used to load resources from a server. If and when your
|
||||
|
|
@ -35,3 +118,8 @@ authentication is done.
|
|||
Similar solution could be used to describe required resources as data (maybe
|
||||
even GraphQL query) per route, and then have code automatically load
|
||||
missing resources.
|
||||
|
||||
|
||||
## Controllers elsewhere
|
||||
|
||||
* [Controllers in Keechma](https://keechma.com/guides/controllers/)
|
||||
|
|
|
|||
Loading…
Reference in a new issue