mirror of
https://github.com/metosin/reitit.git
synced 2025-12-27 11:58:25 +00:00
Improved frontend docs
This commit is contained in:
parent
78decdb23e
commit
ec1463ed00
3 changed files with 97 additions and 12 deletions
|
|
@ -1,12 +1,31 @@
|
|||
# Frontend basics
|
||||
|
||||
* https://github.com/metosin/reitit/tree/master/examples/frontend
|
||||
Reitit frontend integration is built from multiple layers:
|
||||
|
||||
- Core functions which are enchanted with few browser specific
|
||||
features
|
||||
- [Browser integration](./browser.md) for attaching Reitit to hash-change or HTML5
|
||||
history events
|
||||
- Stateful wrapper for easy use of history integration
|
||||
- Optional [controller extension](./controllers.md)
|
||||
|
||||
## Core functions
|
||||
|
||||
`reitit.frontend` provides few useful functions wrapping core functions:
|
||||
|
||||
- `match-by-path` version which parses a URI using JavaScript, including
|
||||
query-string, and also coerces the parameters.
|
||||
- `router` which compiles coercers by default
|
||||
- `match-by-name` and `match-by-name!` with optional `path-paramers` and
|
||||
logging errors to `console.warn` instead of throwing errors (to prevent
|
||||
React breaking due to errors).
|
||||
`match-by-path` version which parses a URI using JavaScript, including
|
||||
query-string, and also [coerces the parameters](../coercion/coercion.md).
|
||||
Coerced parameters are stored in match `:parameters` property. If coercion
|
||||
is not enabled, the original parameters are stored in the same property,
|
||||
to allow the same code to read parameters regardless if coercion is
|
||||
enabled.
|
||||
|
||||
`router` which compiles coercers by default.
|
||||
|
||||
`match-by-name` and `match-by-name!` with optional `path-paramers` and
|
||||
logging errors to `console.warn` instead of throwing errors to prevent
|
||||
React breaking due to errors.
|
||||
|
||||
## Next
|
||||
|
||||
[Browser integration](./browser.md)
|
||||
|
|
|
|||
|
|
@ -21,5 +21,7 @@ Check examples for simple Ring handler example.
|
|||
## Easy
|
||||
|
||||
Reitit frontend routers require storing the state somewhere and passing it to
|
||||
all the calls. Wrapper (`reitit.frontend.easy`) is provided which manages
|
||||
router instance and passes the instance to all calls.
|
||||
all the calls. Wrapper `reitit.frontend.easy` is provided which manages
|
||||
a router instance and passes the instance to all calls. This should
|
||||
allow easy use in most applications, as browser anyway can only have single
|
||||
event handler for page change events.
|
||||
|
|
|
|||
|
|
@ -7,20 +7,84 @@ Controllers run code when a route is entered and left. This can be useful to:
|
|||
- Load resources
|
||||
- Update application state
|
||||
|
||||
## Authentication
|
||||
Controller is map of:
|
||||
|
||||
- All properties are optional
|
||||
- `:params` function, `match` -> controller parameters
|
||||
- `:start` & `:stop` functions
|
||||
|
||||
Controllers are defined in [route data](../basics/route_data.md) and
|
||||
as vectors, like:
|
||||
|
||||
```
|
||||
["/items"
|
||||
{:name :items
|
||||
:controllers [{:start start-fn, :stop stop-fn)}]}]
|
||||
```
|
||||
|
||||
To built hierarchies of controllers, nested route data can be used,
|
||||
due to how Reitit merges the route data for nested routes the vectors are
|
||||
concatenated:
|
||||
|
||||
```
|
||||
["/items"
|
||||
{:controllers [{:start start-common-fn}]} ;; A
|
||||
[""
|
||||
{:name :items
|
||||
:controllers [{:start start-items-fn}]}] ;; B
|
||||
["/:id"
|
||||
{:name :item
|
||||
;; C
|
||||
:controllers [{:params item-param-fn :start start-item-fn}]}]]
|
||||
```
|
||||
|
||||
In this example both `:items` and `:item` routes inherit `:controllers` from
|
||||
their parent route. Lets call these controllers A, B and C. `:items` route
|
||||
has controllers A and B and `:item` A and C.
|
||||
|
||||
Controller `:start` is called when new matches controllers list contains a
|
||||
controller that is not yet initialized. If either of routes is entered
|
||||
from some other route, `:start` is called for both of routes controllers.
|
||||
If `:item` is entered from `:items` only C `:start` is called, because
|
||||
A controller is identical for both routes. And transition from `:item`
|
||||
back to `:items` would only call B `:start`.
|
||||
|
||||
Controller `:stop` function is called for controllers that were
|
||||
initialized but aren't included in the new match.
|
||||
|
||||
To reinitialize a controller when route itself doesn't change,
|
||||
controllers can provide `:params` function to control their
|
||||
identity based on which parameters they are interested in.
|
||||
|
||||
To make C controller depend on routes `id` path parameter, it should
|
||||
provide following function:
|
||||
|
||||
```clj
|
||||
(defn item-param-fn [match]
|
||||
(select-keys (:path (:parameters match)) [:id]))
|
||||
```
|
||||
|
||||
Now, whenever the result value of this function changes, the identity
|
||||
of controller changes and controller is stopped and started.
|
||||
|
||||
TODO: Provide way to declare params as data.
|
||||
|
||||
## Tips
|
||||
|
||||
### Authentication
|
||||
|
||||
Controllers can be used to load resources from a server. If and when your
|
||||
API requires authentication you will need to implement logic to prevent controllers
|
||||
trying to do requests if user isn't authenticated yet.
|
||||
|
||||
### Run controllers and check authentication
|
||||
#### Run controllers and check authentication
|
||||
|
||||
If you have both unauthenticated and authenticated resources, you can
|
||||
run the controllers always and then check the authentication status
|
||||
on controller code, or on the code called from controllers (e.g. re-frame event
|
||||
handler).
|
||||
|
||||
### Disable controllers until user is authenticated
|
||||
#### Disable controllers until user is authenticated
|
||||
|
||||
If all your resources require authentication an easy way to prevent bad
|
||||
requests is to enable controllers only after authentication is done.
|
||||
|
|
|
|||
Loading…
Reference in a new issue