[DOC] qweb: add some documentation on owl qweb extensions

This commit is contained in:
Géry Debongnie
2019-05-16 10:23:18 +02:00
parent 73d743a1c3
commit 7df0fdcc0a
+128 -14
View File
@@ -5,6 +5,7 @@
- [Overview](#overview) - [Overview](#overview)
- [QWeb Engine](#qweb-engine) - [QWeb Engine](#qweb-engine)
- [QWeb Specification](#qweb-specification) - [QWeb Specification](#qweb-specification)
- [Static html nodes](#static-html-nodes) - [Static html nodes](#static-html-nodes)
- [`t-esc` directive](#t-esc-directive) - [`t-esc` directive](#t-esc-directive)
- [`t-raw` directive](#t-raw-directive) - [`t-raw` directive](#t-raw-directive)
@@ -15,6 +16,7 @@
- [`t-call` directive (sub templates)](#t-call-directive-sub-templates) - [`t-call` directive (sub templates)](#t-call-directive-sub-templates)
- [JS/OWL Specific Extensions](#jsowl-specific-extensions) - [JS/OWL Specific Extensions](#jsowl-specific-extensions)
- [`t-on` directive](#t-on-directive) - [`t-on` directive](#t-on-directive)
- [Component: `t-widget`, `t-props`](#component-t-widget-t-props) - [Component: `t-widget`, `t-props`](#component-t-widget-t-props)
- [`t-ref` directive](#t-ref-directive) - [`t-ref` directive](#t-ref-directive)
@@ -40,7 +42,6 @@ templates into functions that output a virtual DOM instead of a string. This is
necessary for the component system. In addition, it has a few extra directives necessary for the component system. In addition, it has a few extra directives
(see [OWL Specific Extensions](#owlspecificextensions)) (see [OWL Specific Extensions](#owlspecificextensions))
## QWeb Engine ## QWeb Engine
This section is about the javascript code that implements the `QWeb` specification. This section is about the javascript code that implements the `QWeb` specification.
@@ -63,7 +64,7 @@ It's API is quite simple:
- **`addTemplate(name, xmlStr)`**: add a specific template. - **`addTemplate(name, xmlStr)`**: add a specific template.
```js ```js
qweb.addTemplate('mytemplate', '<div>hello</div>'); qweb.addTemplate("mytemplate", "<div>hello</div>");
``` ```
- **`addTemplates(xmlStr)`**: add a list of templates (identified by `t-name` - **`addTemplates(xmlStr)`**: add a list of templates (identified by `t-name`
@@ -82,7 +83,7 @@ It's API is quite simple:
which is a virtual representation of the DOM (see [vdom doc](vdom.md)). which is a virtual representation of the DOM (see [vdom doc](vdom.md)).
```js ```js
const vnode = qweb.render('App', widget); const vnode = qweb.render("App", widget);
``` ```
## QWeb Specification ## QWeb Specification
@@ -321,15 +322,112 @@ will result in :
</div> </div>
``` ```
## JS/OWL Specific Extensions ## JS/OWL Specific Extensions
### `t-on` directive ### `t-on` directive
In a component's template, it is useful to be able to register handlers on some
elements to some specific events. This
is what makes a template _alive_. There are two different use cases.
1. Register an event handler on a DOM node
```xml
<button t-on-click="someMethod">Do something</button>
```
This will be roughly translated in javascript like this:
```js
button.addEventListener("click", widget.someMethod.bind(widget));
```
The suffix (`click` in this example) is simply the name of the actual DOM
event.
2. Register an event handler on a component. This will not capture a DOM event,
but rather a _business_ event:
```xml
<t t-widget="MyWidget" t-on-menuLoaded="someMethod"/>
```
```js
class MyWidget {
someWhere() {
const payload = ...;
this.trigger('menuLoaded', payload);
}
}
```
Here, the parent widget will receive the payload in its `someMethod` handler,
whenever the event is triggered.
The `t-on` directive also allows to prebind some arguments. For example,
```xml
<button t-on-click="someMethod(expr)">Do something</button>
```
Here, `expr` is a valid Owl expression, so it could be `true` or some variable
from the rendering context.
### Component: `t-widget`, `t-props` ### Component: `t-widget`, `t-props`
The `t-widget` and the `t-props` directives are the key to a declarative component
system. They allow a template to define where and how a sub widget is created
and/or updated. For example:
```xml
<div t-name="ParentWidget">
<t t-widget="ChildWidget" t-props="{count: state.val}"/>
</div>
```
```js
class ParentWidget {
widgets = { ChildWidget };
state = { val: 4 };
}
```
Whenever the template is rendered, it will automatically create the subwidget
`ChildWidget` at the correct place. It needs to find the reference to the
actual component class in the special `widgets` key.
In this example, the child widget will receive the object `{count: 4}` in its
constructor. This will be assigned to the `props` variable, which can be accessed
on the widget (and also, in the template). Whenever the state is updated, then
the subwidget will also be updated automatically.
### `t-ref` directive ### `t-ref` directive
The `t-ref` directive helps a component keep reference to some inside part of it.
Like the `t-on` directive, it can work either on a DOM node, or on a component:
```xml
<div>
<div t-ref="someDiv"/>
<t t-widget="SubWidget" t-ref="someWidget"/>
</div>
```
In this example, the widget will be able to access the `div` and the component
inside the special `refs` variable:
```js
this.refs.someDiv;
this.refs.someWidget;
```
This is useful for various usecases: for example, integrating with an external
library that needs to render itself inside an actual DOM node. Or for calling
some method on a sub widget.
Note: if used on a component, the reference will be set in the `refs`
variable between `willPatch` and `patched`.
### `t-key` directive ### `t-key` directive
Even though Owl tries to be as declarative as possible, some DOM state is still Even though Owl tries to be as declarative as possible, some DOM state is still
@@ -341,17 +439,18 @@ the same, or is different. The `t-key` directive is used to give an identity to
There are three main use cases: There are three main use cases:
- *elements in a list*: - _elements in a list_:
```xml ```xml
<span t-foreach="todos" t-as="todo" t-key="todo.id"> <span t-foreach="todos" t-as="todo" t-key="todo.id">
<t t-esc="todo.text"/> <t t-esc="todo.text"/>
</span> </span>
``` ```
- *`t-if`/`t-else`* - _`t-if`/`t-else`_
- *animations*: give a different identity to a component. Ex: thread id with - _animations_: give a different identity to a component. Ex: thread id with
animations on add/remove message. animations on add/remove message.
### `t-transition` directive ### `t-transition` directive
@@ -374,6 +473,7 @@ At node creation:
ends. ends.
At node destruction: At node destruction:
- the css classes `name-leave` and `name-leave-active` will be added before the - the css classes `name-leave` and `name-leave-active` will be added before the
node is removed to the DOM, node is removed to the DOM,
- the css class `name-leave` will be removed on the next animation frame (so it - the css class `name-leave` will be removed on the next animation frame (so it
@@ -390,10 +490,12 @@ For example, a simple fade in/out effect can be done with this:
``` ```
```css ```css
.fade-enter-active, .fade-leave-active { .fade-enter-active,
transition: opacity .5s; .fade-leave-active {
transition: opacity 0.5s;
} }
.fade-enter, .fade-leave-to { .fade-enter,
.fade-leave-to {
opacity: 0; opacity: 0;
} }
``` ```
@@ -402,9 +504,22 @@ Note: more information on animations are available [here](doc/animations.md).
### `t-mounted` directive ### `t-mounted` directive
The `t-mounted` directive allows to register a callback to execute when the node The `t-mounted` directive allows to register a callback to execute whenever the node
is inserted into the DOM. is inserted into the DOM.
```xml
<div><input t-ref="someInput" t-mounted="focusMe"/></div>
```
```js
class MyWidget extends owl.Component {
...
focusMe() {
this.refs.someInput.focus();
}
}
```
### Debugging (`t-debug` and `t-log`) ### Debugging (`t-debug` and `t-log`)
The javascript QWeb implementation provides two useful debugging directives: The javascript QWeb implementation provides two useful debugging directives:
@@ -415,7 +530,7 @@ The javascript QWeb implementation provides two useful debugging directives:
<t t-if="a_test"> <t t-if="a_test">
<t t-debug=""> <t t-debug="">
</t> </t>
```` ```
will stop execution if the browser dev tools are open. will stop execution if the browser dev tools are open.
@@ -428,7 +543,6 @@ will stop execution if the browser dev tools are open.
will print 42 to the console will print 42 to the console
### White spaces ### White spaces
White spaces in a templates are handled in a special way: White spaces in a templates are handled in a special way: