mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
83532db48f
part of #430
182 lines
5.5 KiB
Markdown
182 lines
5.5 KiB
Markdown
# 🦉 Router 🦉
|
|
|
|
## Content
|
|
|
|
- [Overview](#overview)
|
|
- [Example](#example)
|
|
- [Reference](#reference)
|
|
- [Route Definition](#route-definition)
|
|
- [Router](#router)
|
|
- [Navigation Guards](#navigation-guards)
|
|
- [RouteComponent](#routecomponent)
|
|
- [Link](#link)
|
|
|
|
## Overview
|
|
|
|
It is often useful to organize an application around urls. If the application is
|
|
a single page application, then we need a way to manage those urls in the browser.
|
|
This is why there are many different routers for different frameworks. A generic
|
|
router can do the job just fine, but a specialized router for Owl can give a
|
|
better developer experience.
|
|
|
|
The Owl router support the following features:
|
|
|
|
- `history` or `hash` mode
|
|
- declarative routes
|
|
- route redirection
|
|
- navigation guards
|
|
- parameterized routes
|
|
- a `<Link/>` component
|
|
- a `<RouteComponent/>` component
|
|
|
|
Note that it is still in early stage of developments, and there are probably
|
|
still some issues.
|
|
|
|
## Example
|
|
|
|
To use the Owl router, there are some steps that needs to be done:
|
|
|
|
- declare some routes
|
|
- create a router
|
|
- add it to the environment
|
|
|
|
```js
|
|
async function protectRoute({ env, to }) {
|
|
if (!env.session.authUser) {
|
|
env.session.setNextRoute(to.name);
|
|
return { to: "SIGN_IN" };
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export const ROUTES = [
|
|
{ name: "LANDING", path: "/", component: Landing },
|
|
{ name: "TASK", path: "/tasks/{{id}}", component: Task },
|
|
{ name: "SIGN_UP", path: "/signup", component: SignUp },
|
|
{ name: "SIGN_IN", path: "/signin", component: SignIn },
|
|
{ name: "ADMIN", path: "/admin", component: Admin, beforeRouteEnter: protectRoute },
|
|
{ name: "ACCOUNT", path: "/account", component: Account, beforeRouteEnter: protectRoute },
|
|
{ name: "UNKNOWN", path: "*", redirect: { to: "LANDING" } }
|
|
];
|
|
|
|
function makeEnvironment() {
|
|
...
|
|
const env = { qweb };
|
|
env.session = new Session(env);
|
|
env.router = new owl.router.Router(env, ROUTES);
|
|
await env.router.start();
|
|
return env;
|
|
}
|
|
|
|
App.env = makeEnvironment();
|
|
// create root component here
|
|
```
|
|
|
|
Notice that the router needs to be started. This is an asynchronous operation
|
|
because it needs to apply the potential navigation guards on the current route
|
|
(which may or may not mean that the application is redirected to another route).
|
|
|
|
## Reference
|
|
|
|
### Route definition
|
|
|
|
A route need to be defined as an object with the following keys:
|
|
|
|
- `name` (optional): a (unique) string useful to identify the current route. If not
|
|
given, it will be assigned an automatic name,
|
|
- `path`: a string describing the url. It can be static: `/admin` or dynamic: `/users/{{id}}`.
|
|
It also can be `*`, to catch all remaining routes.
|
|
- `component` (optional): an Owl component that will be used by the `t-routecomponent`
|
|
directive if the route is active
|
|
- `redirect` (optional): should be destination object (with optional keys `path`, `to` and `params`) if given, the application will be redirected to the destination whenever we match this route
|
|
- `beforeRouteEnter`: defines a [navigation guard](#navigation-guards).
|
|
|
|
### `Router`
|
|
|
|
The `Router` constructor takes three arguments:
|
|
|
|
- `env`: a valid environment,
|
|
- a list of routes,
|
|
- an optional object (with the only key `mode` which can be `history` (default
|
|
value) or `hash`).
|
|
|
|
`history` will use the browser [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) as the mechanism to manage URL.\
|
|
Example: `https://yourdomain.tld/my_custom_route`.\
|
|
For this mechanism to work, you need a way to configure your web server accordingly.
|
|
|
|
`hash` will manipulate the hash of the URL.\
|
|
Example: `https://yourdomain.tld/index.html#/my_custom_route`.
|
|
|
|
```js
|
|
const ROUTES = [...];
|
|
const router = new owl.router.Router(env, ROUTES, {mode: 'history'});
|
|
```
|
|
|
|
Note that the route are defined in a list, and the order matters: the router
|
|
tries to find a match by going down the list.
|
|
|
|
The router needs to be added to the environment in the `router` sub key.
|
|
|
|
Once a router is created, it needs to be started. This is necessary to initialize
|
|
its current state to the current URL (and also, to potentially apply any
|
|
navigation guards and/or redirecting).
|
|
|
|
```js
|
|
await router.start();
|
|
```
|
|
|
|
Once started, the router will keep track of the current url and reflect its
|
|
value in two keys:
|
|
|
|
- `router.currentRoute`
|
|
- `router.currentParams`
|
|
|
|
The router also has a `navigate` method, useful to programmatically change the
|
|
application to another state (and the url):
|
|
|
|
```js
|
|
router.navigate({ to: "USER", params: { id: 51 } });
|
|
```
|
|
|
|
### Navigation Guards
|
|
|
|
Navigation guards are very useful to be able to execute some business logic/
|
|
perform some actions or redirect to other routes whenever the application is
|
|
entering a new route. For example, the following guard checks if there is an
|
|
authenticated user, and if it is not the case, redirect to the sign in route.
|
|
|
|
```js
|
|
async function protectRoute({ env, to }) {
|
|
if (!env.session.authUser) {
|
|
env.session.setNextRoute(to.name);
|
|
return { to: "SIGN_IN" };
|
|
}
|
|
return true;
|
|
}
|
|
```
|
|
|
|
A navigation guard is a function that returns a promise, which either resolves
|
|
to `true` (the navigation is accepted), or to another destination object.
|
|
|
|
### `RouteComponent`
|
|
|
|
The `RouteComponent` component directs Owl to render the component associated
|
|
to the currently active route (if any):
|
|
|
|
```xml
|
|
<div t-name="App">
|
|
<NavBar />
|
|
<RouteComponent />
|
|
</div>
|
|
```
|
|
|
|
### `Link`
|
|
|
|
The `Link` component is a Owl component which render as a `<a>` tag with any
|
|
content. It will compute the proper href from its props, and allow Owl to
|
|
properly navigate to a given url if clicked on it.
|
|
|
|
```xml
|
|
<Link to="'HOME'">Home</Link>
|
|
```
|