[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
+127 -13
View File
@@ -5,6 +5,7 @@
- [Overview](#overview)
- [QWeb Engine](#qweb-engine)
- [QWeb Specification](#qweb-specification)
- [Static html nodes](#static-html-nodes)
- [`t-esc` directive](#t-esc-directive)
- [`t-raw` directive](#t-raw-directive)
@@ -15,6 +16,7 @@
- [`t-call` directive (sub templates)](#t-call-directive-sub-templates)
- [JS/OWL Specific Extensions](#jsowl-specific-extensions)
- [`t-on` directive](#t-on-directive)
- [Component: `t-widget`, `t-props`](#component-t-widget-t-props)
- [`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
(see [OWL Specific Extensions](#owlspecificextensions))
## QWeb Engine
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.
```js
qweb.addTemplate('mytemplate', '<div>hello</div>');
qweb.addTemplate("mytemplate", "<div>hello</div>");
```
- **`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)).
```js
const vnode = qweb.render('App', widget);
const vnode = qweb.render("App", widget);
```
## QWeb Specification
@@ -321,15 +322,112 @@ will result in :
</div>
```
## JS/OWL Specific Extensions
### `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`
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
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
Even though Owl tries to be as declarative as possible, some DOM state is still
@@ -341,16 +439,17 @@ the same, or is different. The `t-key` directive is used to give an identity to
There are three main use cases:
- *elements in a list*:
- _elements in a list_:
```xml
<span t-foreach="todos" t-as="todo" t-key="todo.id">
<t t-esc="todo.text"/>
</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.
### `t-transition` directive
@@ -374,6 +473,7 @@ At node creation:
ends.
At node destruction:
- the css classes `name-leave` and `name-leave-active` will be added before the
node is removed to the DOM,
- 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
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
.fade-enter,
.fade-leave-to {
opacity: 0;
}
```
@@ -402,9 +504,22 @@ Note: more information on animations are available [here](doc/animations.md).
### `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.
```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`)
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-debug="">
</t>
````
```
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
### White spaces
White spaces in a templates are handled in a special way: