mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
@@ -28,7 +28,7 @@ Owl is currently mostly stable. Possible future changes are explained in the
|
|||||||
Here is a short example to illustrate interactive components:
|
Here is a short example to illustrate interactive components:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const { Component, QWeb, useState } = owl;
|
const { Component, useState } = owl;
|
||||||
const { xml } = owl.tags;
|
const { xml } = owl.tags;
|
||||||
|
|
||||||
class Counter extends Component {
|
class Counter extends Component {
|
||||||
@@ -50,7 +50,7 @@ class App extends Component {
|
|||||||
static components = { Counter };
|
static components = { Counter };
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new App({ qweb: new QWeb() });
|
const app = new App();
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ A complete documentation for Owl can be found here:
|
|||||||
|
|
||||||
The most important sections are:
|
The most important sections are:
|
||||||
|
|
||||||
- [Quick Start](doc/quick_start.md)
|
- [Quick Start](doc/learning/quick_start.md)
|
||||||
- [Component](doc/reference/component.md)
|
- [Component](doc/reference/component.md)
|
||||||
- [Hooks](doc/reference/hooks.md)
|
- [Hooks](doc/reference/hooks.md)
|
||||||
|
|
||||||
@@ -127,23 +127,6 @@ Owl components in an application are used to define a (dynamic) tree of componen
|
|||||||
C D
|
C D
|
||||||
```
|
```
|
||||||
|
|
||||||
**Environment:** the root component is special: it is created with an environment,
|
|
||||||
which should contain a [`QWeb` instance](doc/reference/qweb.md). The environment is then automatically
|
|
||||||
propagated to each sub components (and accessible in the `this.env` property).
|
|
||||||
|
|
||||||
```js
|
|
||||||
const env = { qweb: new QWeb() };
|
|
||||||
const app = new App(env);
|
|
||||||
app.mount(document.body);
|
|
||||||
```
|
|
||||||
|
|
||||||
The environment is mostly static. Each application is free to add anything to
|
|
||||||
the environment, which is very useful, since this can be accessed by each sub
|
|
||||||
component. Some good use case for that is some configuration keys, session
|
|
||||||
information or generic services (such as doing rpcs, or accessing local storage).
|
|
||||||
Doing it this way means that components are easily testable: we can simply
|
|
||||||
create a test environment with mock services.
|
|
||||||
|
|
||||||
**State:** each component can manage its own local state. It is a simple ES6
|
**State:** each component can manage its own local state. It is a simple ES6
|
||||||
class, there are no special rules:
|
class, there are no special rules:
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -274,7 +274,8 @@ class Counter extends Component {
|
|||||||
dispatch = useDispatch();
|
dispatch = useDispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
const counter = new Counter({ store, qweb });
|
owl.config.env.store = store;
|
||||||
|
const counter = new Counter();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Hooks
|
## Hooks
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# 🦉 Environment 🦉
|
||||||
|
|
||||||
|
An environment is an object which contains a [`QWeb` instance](../reference/qweb.md).
|
||||||
|
Whenever a root component is created, it is assigned an environment (see the
|
||||||
|
reference section on [environment](../reference/environment.md). This environment
|
||||||
|
is then automatically given to each sub components (and accessible in the `this.env` property).
|
||||||
|
|
||||||
|
The environment is mostly static. Each application is free to add anything to
|
||||||
|
the environment, which is very useful, since this can be accessed by each sub
|
||||||
|
component.
|
||||||
|
|
||||||
|
Some good use cases for the environment is:
|
||||||
|
|
||||||
|
- some configuration keys,
|
||||||
|
- session information,
|
||||||
|
- generic services (such as doing rpcs, or accessing local storage).
|
||||||
|
|
||||||
|
Doing it this way means that components are easily testable: we can simply
|
||||||
|
create a test environment with mock services.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
async function myEnv() {
|
||||||
|
const templates = await loadTemplates();
|
||||||
|
const qweb = new QWeb({templates});
|
||||||
|
const session = getSession();
|
||||||
|
|
||||||
|
return {
|
||||||
|
_t: myTranslateFunction,
|
||||||
|
session: session,
|
||||||
|
qweb: qweb,
|
||||||
|
services: {
|
||||||
|
localStorage: localStorage,
|
||||||
|
rpc: rpc,
|
||||||
|
},
|
||||||
|
debug: false,
|
||||||
|
inMobileMode: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function start() {
|
||||||
|
owl.config.env = await myEnv();
|
||||||
|
const app = new App();
|
||||||
|
await app.mount(document.body);
|
||||||
|
}
|
||||||
|
```
|
||||||
+10
-4
@@ -12,6 +12,9 @@ owl
|
|||||||
QWeb
|
QWeb
|
||||||
Store
|
Store
|
||||||
useState
|
useState
|
||||||
|
config
|
||||||
|
mode
|
||||||
|
env
|
||||||
core
|
core
|
||||||
EventBus
|
EventBus
|
||||||
Observer
|
Observer
|
||||||
@@ -48,11 +51,18 @@ owl
|
|||||||
|
|
||||||
Note that for convenience, the `useState` hook is also exported at the root of the `owl` object.
|
Note that for convenience, the `useState` hook is also exported at the root of the `owl` object.
|
||||||
|
|
||||||
|
## Learning Resources
|
||||||
|
|
||||||
|
- [Quick Start: create an (almost) empty Owl application](learning/quick_start.md)
|
||||||
|
- [Environment: what it is and what it should contain](learning/environment.md)
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
- [Animations](reference/animations.md)
|
- [Animations](reference/animations.md)
|
||||||
- [Component](reference/component.md)
|
- [Component](reference/component.md)
|
||||||
|
- [Configuration](reference/config.md)
|
||||||
- [Context](reference/context.md)
|
- [Context](reference/context.md)
|
||||||
|
- [Environment](reference/environment.md)
|
||||||
- [Event Bus](reference/event_bus.md)
|
- [Event Bus](reference/event_bus.md)
|
||||||
- [Hooks](reference/hooks.md)
|
- [Hooks](reference/hooks.md)
|
||||||
- [Misc](reference/misc.md)
|
- [Misc](reference/misc.md)
|
||||||
@@ -63,10 +73,6 @@ Note that for convenience, the `useState` hook is also exported at the root of t
|
|||||||
- [Tags](reference/tags.md)
|
- [Tags](reference/tags.md)
|
||||||
- [Utils](reference/utils.md)
|
- [Utils](reference/utils.md)
|
||||||
|
|
||||||
## Learning Resources
|
|
||||||
|
|
||||||
- [Quick Start: create an (almost) empty Owl application](learning/quick_start.md)
|
|
||||||
|
|
||||||
## Miscellaneous
|
## Miscellaneous
|
||||||
|
|
||||||
- [Comparison with React/Vue](comparison.md)
|
- [Comparison with React/Vue](comparison.md)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
- [Methods](#methods)
|
- [Methods](#methods)
|
||||||
- [Lifecycle](#lifecycle)
|
- [Lifecycle](#lifecycle)
|
||||||
- [Root Component](#root-component)
|
- [Root Component](#root-component)
|
||||||
- [Environment](#environment)
|
|
||||||
- [Composition](#composition)
|
- [Composition](#composition)
|
||||||
- [Event Handling](#event-handling)
|
- [Event Handling](#event-handling)
|
||||||
- [Form Input Bindings](#form-input-bindings)
|
- [Form Input Bindings](#form-input-bindings)
|
||||||
@@ -81,8 +80,8 @@ a state object is defined, by using the `useState` hook. It is not mandatory to
|
|||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
An Owl component is a small class which represents a component or some UI element.
|
An Owl component is a small class which represents a component or some UI element.
|
||||||
It exists in the context of an environment (`env`), which is propagated from a
|
It exists in the context of an [environment](environment.md) (`env`), which is propagated from a
|
||||||
parent to its children. The environment needs to have a QWeb instance, which
|
parent to its children. The environment needs to have a [QWeb](qweb.md) instance, which
|
||||||
will be used to render the component template.
|
will be used to render the component template.
|
||||||
|
|
||||||
Be aware that the name of the component may be significant: if a component does
|
Be aware that the name of the component may be significant: if a component does
|
||||||
@@ -441,49 +440,12 @@ of an Owl application has to be created manually:
|
|||||||
```js
|
```js
|
||||||
class App extends owl.Component { ... }
|
class App extends owl.Component { ... }
|
||||||
|
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES });
|
const app = new App();
|
||||||
const env = { qweb: qweb };
|
|
||||||
const app = new App(env);
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
```
|
```
|
||||||
|
|
||||||
The root component needs an environment.
|
The root component does not have a parent nor props. It will be setup with an
|
||||||
|
[environment](environment.md) (located in `owl.config.env`).
|
||||||
### Environment
|
|
||||||
|
|
||||||
In Owl, an environment is an object with a `qweb` key, which has to be a
|
|
||||||
[QWeb](qweb.md) instance. This qweb instance will be used to render everything.
|
|
||||||
|
|
||||||
The environment is meant to contain (mostly) static global information and
|
|
||||||
methods for the whole application. For example, settings keys (`mode` to determine
|
|
||||||
if we are in desktop or mobile mode, or `theme`: dark or light), `rpc` methods,
|
|
||||||
session information, ...
|
|
||||||
|
|
||||||
The environment will be given to each child, unchanged, in the `env` property.
|
|
||||||
This can be very useful to share common information/methods. For example, all
|
|
||||||
rpcs can be made through a `rpc` method in the environment. This makes it very
|
|
||||||
easy to test a component.
|
|
||||||
|
|
||||||
Updating the environment is not as simple as changing a component's state: its
|
|
||||||
content is not observed, so updates will not be reflected immediately in the
|
|
||||||
user interface. There is however a mechanism to force root widgets to rerender
|
|
||||||
themselves whenever the environment is modified: one only needs to call the
|
|
||||||
`forceUpdate` method on the QWeb instance. For example, a responsive environment
|
|
||||||
could be done like this:
|
|
||||||
|
|
||||||
```js
|
|
||||||
function setupResponsivePlugin(env) {
|
|
||||||
const isMobile = () => window.innerWidth <= 768;
|
|
||||||
env.isMobile = isMobile();
|
|
||||||
const updateEnv = owl.utils.debounce(() => {
|
|
||||||
if (env.isMobile !== isMobile()) {
|
|
||||||
env.isMobile = !env.isMobile;
|
|
||||||
env.qweb.forceUpdate();
|
|
||||||
}
|
|
||||||
}, 15);
|
|
||||||
window.addEventListener("resize", updateEnv);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Composition
|
### Composition
|
||||||
|
|
||||||
@@ -986,7 +948,7 @@ of the props. Here is how it works in Owl:
|
|||||||
- `props` key is a static key (so, different from `this.props` in a component instance)
|
- `props` key is a static key (so, different from `this.props` in a component instance)
|
||||||
- it is optional: it is ok for a component to not define a `props` key.
|
- it is optional: it is ok for a component to not define a `props` key.
|
||||||
- props are validated whenever a component is created/updated
|
- props are validated whenever a component is created/updated
|
||||||
- props are only validated in `dev` mode (see [tooling page](../tooling.md#development-mode))
|
- props are only validated in `dev` mode (see [config page](config.md#mode))
|
||||||
- if a key does not match the description, an error is thrown
|
- if a key does not match the description, an error is thrown
|
||||||
- it validates keys defined in (static) `props`. Additional keys given by the
|
- it validates keys defined in (static) `props`. Additional keys given by the
|
||||||
parent will cause an error.
|
parent will cause an error.
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# 🦉 Config 🦉
|
||||||
|
|
||||||
|
The Owl framework is designed to work in many situations. However, it is
|
||||||
|
sometimes necessary to customize some behaviour. This is done by using the
|
||||||
|
global `config` object. It currently has two keys:
|
||||||
|
|
||||||
|
- [`mode`](#mode),
|
||||||
|
- [`env`](#env).
|
||||||
|
|
||||||
|
## Mode
|
||||||
|
|
||||||
|
By default, Owl is in _production_ mode, this means that it will try to do its
|
||||||
|
job fast, and skip some expensive operations. However, it is sometimes necessary
|
||||||
|
to have better information on what is going on, this is the purpose
|
||||||
|
of the `dev` mode.
|
||||||
|
|
||||||
|
Owl has a mode flag, in `owl.config.mode`. Its default value is `prod`, but
|
||||||
|
it can be set to `dev`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
owl.config.mode = "dev";
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that templates compiled with the `prod` settings will not be recompiled.
|
||||||
|
So, changing this setting is best done at startup.
|
||||||
|
|
||||||
|
An important job done by the `dev` mode is to validate props for each component
|
||||||
|
creation and update. Also, extra props will cause an error.
|
||||||
|
|
||||||
|
## Env
|
||||||
|
|
||||||
|
An Owl application needs an [environment](environment.md) to be executed. The
|
||||||
|
environment has an important key: the [QWeb](qweb.md) instance, which will render
|
||||||
|
all templates.
|
||||||
|
|
||||||
|
Whenever a root component is mounted, Owl will take the environment from
|
||||||
|
`owl.config.env` and use it to setup the component (and its children).
|
||||||
|
|
||||||
|
- if no environment was setup, an empty environment will be generated,
|
||||||
|
- if an environment exists, but does not have a QWeb key, a new QWeb instance
|
||||||
|
will then be added to the environment.
|
||||||
|
|
||||||
|
The correct way to customize an environment is to simply modify `owl.config.env`
|
||||||
|
before the first component is created:
|
||||||
|
|
||||||
|
```js
|
||||||
|
owl.config.env = {
|
||||||
|
_t: myTranslateFunction,
|
||||||
|
user: {...},
|
||||||
|
services: {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const app = new App();
|
||||||
|
app.mount(document.body);
|
||||||
|
```
|
||||||
@@ -28,10 +28,7 @@ context, and add it to the environment:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
const deviceContext = new Context({ isMobile: true });
|
const deviceContext = new Context({ isMobile: true });
|
||||||
const env = {
|
owl.config.env.deviceContext = deviceContext;
|
||||||
qweb: new QWeb({ templates: TEMPLATES }),
|
|
||||||
deviceContext
|
|
||||||
};
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If we want to make it completely responsive, we need to update its value whenever
|
If we want to make it completely responsive, we need to update its value whenever
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# 🦉 Environment 🦉
|
||||||
|
|
||||||
|
An environment is an object which contains a [`QWeb` instance](qweb.md). Whenever a root component is created, it is assigned an environment. This environment
|
||||||
|
is then automatically given to each sub component (and accessible in the `this.env` property).
|
||||||
|
|
||||||
|
```
|
||||||
|
Root
|
||||||
|
/ \
|
||||||
|
A B
|
||||||
|
```
|
||||||
|
|
||||||
|
This way, all components share the same `QWeb` instance.
|
||||||
|
|
||||||
|
Note: some additional information can be found here:
|
||||||
|
|
||||||
|
- [What should go into an environment?](../learning/environment.md)
|
||||||
|
- [Customizing an environment](config.md#env)
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ Its API is quite simple:
|
|||||||
```
|
```
|
||||||
|
|
||||||
In some way, a `QWeb` instance is the core of an Owl application. It is the only
|
In some way, a `QWeb` instance is the core of an Owl application. It is the only
|
||||||
mandatory element of an [environment](component.md#environment). As such, it
|
mandatory element of an [environment](environment.md). As such, it
|
||||||
has an extra responsibility: it can act as an event bus for internal communication
|
has an extra responsibility: it can act as an event bus for internal communication
|
||||||
between Owl classes. This is the reason why `QWeb` actually extends [EventBus](event_bus.md).
|
between Owl classes. This is the reason why `QWeb` actually extends [EventBus](event_bus.md).
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ function makeEnvironment() {
|
|||||||
await env.router.start();
|
await env.router.start();
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
owl.config.env = makeEnvironment();
|
||||||
|
// create root component here
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice that the router needs to be started. This is an asynchronous operation
|
Notice that the router needs to be started. This is an asynchronous operation
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
## Content
|
## Content
|
||||||
|
|
||||||
- [Overview](#overview)
|
- [Overview](#overview)
|
||||||
- [Development Mode](#development-mode)
|
|
||||||
- [Playground](#playground)
|
- [Playground](#playground)
|
||||||
- [Benchmarks](#benchmarks)
|
- [Benchmarks](#benchmarks)
|
||||||
- [Single File Component](#single-file-component)
|
- [Single File Component](#single-file-component)
|
||||||
@@ -21,26 +20,6 @@ by using a static http server. A simple python
|
|||||||
server is available in `server.py`. There is also a npm script to start it:
|
server is available in `server.py`. There is also a npm script to start it:
|
||||||
`npm run tools` (and its version with a watcher: `npm run tools:watch`).
|
`npm run tools` (and its version with a watcher: `npm run tools:watch`).
|
||||||
|
|
||||||
## Development Mode
|
|
||||||
|
|
||||||
By default, Owl is in _production_ mode, this means that it will try to do its
|
|
||||||
job fast, and skip some expensive operations. However, in some cases, it is
|
|
||||||
convenient to have better information on what is going on, this is the purpose
|
|
||||||
of the dev mode.
|
|
||||||
|
|
||||||
Owl has a mode flag, in `owl.__info__.mode`. Its default value is `prod`, but
|
|
||||||
it can be set to `dev`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
owl.__info__.mode = "dev";
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that templates compiled with the `prod` settings will not be recompiled.
|
|
||||||
So, changing this setting is best done at startup.
|
|
||||||
|
|
||||||
An important job done by the `dev` mode is to validate props for each component
|
|
||||||
creation and update. Also, extra props will cause an error.
|
|
||||||
|
|
||||||
## Playground
|
## Playground
|
||||||
|
|
||||||
The playground is an important application designed to help learning and
|
The playground is an important application designed to help learning and
|
||||||
|
|||||||
Reference in New Issue
Block a user