mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+5
-4
@@ -677,7 +677,6 @@ to event `menu-loaded` will receive the payload in its `someMethod` handler
|
|||||||
|
|
||||||
By convention, we use KebabCase for the name of _business_ events.
|
By convention, we use KebabCase for the name of _business_ events.
|
||||||
|
|
||||||
|
|
||||||
The `t-on` directive allows to prebind some arguments. For example,
|
The `t-on` directive allows to prebind some arguments. For example,
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -695,10 +694,12 @@ One can also directly specify inline statements. For example,
|
|||||||
|
|
||||||
Here, `state` must be defined in the rendering context (typically the component)
|
Here, `state` must be defined in the rendering context (typically the component)
|
||||||
as it will be translated to:
|
as it will be translated to:
|
||||||
```js
|
|
||||||
button.addEventListener("click", () => { component.state.counter++; });
|
|
||||||
```
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
component.state.counter++;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
In order to remove the DOM event details from the event handlers (like calls to
|
In order to remove the DOM event details from the event handlers (like calls to
|
||||||
`event.preventDefault`) and let them focus on data logic, _modifiers_ can be
|
`event.preventDefault`) and let them focus on data logic, _modifiers_ can be
|
||||||
|
|||||||
+10
-3
@@ -1,8 +1,15 @@
|
|||||||
# 🦉 Tags 🦉
|
# 🦉 Tags 🦉
|
||||||
|
|
||||||
|
## Content
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [`xml` tag](#xml-tag)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
Tags are very small helpers to make it easy to write inline templates. There is
|
Tags are very small helpers to make it easy to write inline templates. There is
|
||||||
only one currently available tag: `xml`, but we plan to add other tags later,
|
only one currently available tag: `xml`, but we plan to add other tags later,
|
||||||
such as a `css` tag, which will be used to write single file components.
|
such as a `css` tag, which will be used to write [single file components](tooling.md#single-file-component).
|
||||||
|
|
||||||
## XML tag
|
## XML tag
|
||||||
|
|
||||||
@@ -31,8 +38,8 @@ With tags, this process is slightly simplified. The name is uniquely generated,
|
|||||||
and the template is automatically registered:
|
and the template is automatically registered:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { Component } from 'owl'
|
const { Component } = owl;
|
||||||
import { xml } from 'owl/tags'
|
const { xml } = owl.tags;
|
||||||
|
|
||||||
class MyComponent extends Component {
|
class MyComponent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
|
|||||||
+18
-4
@@ -60,12 +60,21 @@ useful to compare various performance metrics on some tasks.
|
|||||||
|
|
||||||
## Single File Component
|
## Single File Component
|
||||||
|
|
||||||
If you want to have `xml` syntax highlighting while using the `xml` helper which
|
It is very useful to group code by feature instead of by type of file. It makes
|
||||||
helps you define inline templates, there is a VS Code addon `Comment tagged template`
|
it easier to scale application to larger size.
|
||||||
which, if installed, does exactly that. To enable it, you need to add a comment,
|
|
||||||
like this:
|
To do so, Owl currently has a small helper that makes it easy to define a
|
||||||
|
template inside a javascript (or typescript) file: the [`xml`](tags.md#xml-tag)
|
||||||
|
helper. With this, a template is automatically registered to [QWeb](qweb.md).
|
||||||
|
|
||||||
|
This means that the template and the javascript code can be defined in the same
|
||||||
|
file. It is not currently possible to add css to the same file, but Owl may
|
||||||
|
get a `css` tag helper later.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
const { Component } = owl;
|
||||||
|
const { xml } = owl.tags;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// TEMPLATE
|
// TEMPLATE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -85,3 +94,8 @@ class MyComponent extends Component {
|
|||||||
// rest of component...
|
// rest of component...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that the above example has an inline xml comment, just after the `xml` call.
|
||||||
|
This is useful for some editor plugins, such as the VS Code addon
|
||||||
|
`Comment tagged template`, which, if installed, add syntax highlighting to the
|
||||||
|
content of the template string.
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ QWeb.addDirective({
|
|||||||
ctx.addLine(`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`);
|
ctx.addLine(`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`);
|
||||||
} else {
|
} else {
|
||||||
const handlerKey = `handler${ctx.generateID()}`;
|
const handlerKey = `handler${ctx.generateID()}`;
|
||||||
ctx.addLine(`const ${handlerKey} = context['${handlerName}'] && context['${handlerName}'].bind(${params});`);
|
ctx.addLine(
|
||||||
|
`const ${handlerKey} = context['${handlerName}'] && context['${handlerName}'].bind(${params});`
|
||||||
|
);
|
||||||
handler += `if (${handlerKey}) { ${handlerKey}(e); } else { context.${value}; }`;
|
handler += `if (${handlerKey}) { ${handlerKey}(e); } else { context.${value}; }`;
|
||||||
handler += `}`;
|
handler += `}`;
|
||||||
ctx.addLine(`p${nodeID}.on['${eventName}'] = ${handler};`);
|
ctx.addLine(`p${nodeID}.on['${eventName}'] = ${handler};`);
|
||||||
|
|||||||
@@ -2142,7 +2142,7 @@ describe("other directives with t-component", () => {
|
|||||||
<Child t-on-ev="handler"/>
|
<Child t-on-ev="handler"/>
|
||||||
</div>`;
|
</div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({counter: 0});
|
state = useState({ counter: 0 });
|
||||||
get handler() {
|
get handler() {
|
||||||
this.state.counter++;
|
this.state.counter++;
|
||||||
return () => {};
|
return () => {};
|
||||||
@@ -2152,12 +2152,12 @@ describe("other directives with t-component", () => {
|
|||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
|
|
||||||
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
|
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
|
||||||
expect(fixture.innerHTML).toBe('<div>0<span></span></div>');
|
expect(fixture.innerHTML).toBe("<div>0<span></span></div>");
|
||||||
|
|
||||||
let child = children(parent)[0];
|
let child = children(parent)[0];
|
||||||
child.trigger("ev");
|
child.trigger("ev");
|
||||||
await nextTick();
|
await nextTick();
|
||||||
expect(fixture.innerHTML).toBe('<div>1<span></span></div>');
|
expect(fixture.innerHTML).toBe("<div>1<span></span></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-on with inline statement", async () => {
|
test("t-on with inline statement", async () => {
|
||||||
@@ -2171,18 +2171,18 @@ describe("other directives with t-component", () => {
|
|||||||
<Child t-on-ev="state.counter++"/>
|
<Child t-on-ev="state.counter++"/>
|
||||||
</div>`;
|
</div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({counter: 0});
|
state = useState({ counter: 0 });
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent(env);
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
|
|
||||||
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
|
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
|
||||||
expect(fixture.innerHTML).toBe('<div>0<span></span></div>');
|
expect(fixture.innerHTML).toBe("<div>0<span></span></div>");
|
||||||
|
|
||||||
let child = children(parent)[0];
|
let child = children(parent)[0];
|
||||||
child.trigger("ev");
|
child.trigger("ev");
|
||||||
await nextTick();
|
await nextTick();
|
||||||
expect(fixture.innerHTML).toBe('<div>1<span></span></div>');
|
expect(fixture.innerHTML).toBe("<div>1<span></span></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-on with no handler (only modifiers)", async () => {
|
test("t-on with no handler (only modifiers)", async () => {
|
||||||
|
|||||||
@@ -1044,8 +1044,8 @@ describe("t-on", () => {
|
|||||||
qweb.addTemplate("test", `<button t-on-click="state.counter++">Click</button>`);
|
qweb.addTemplate("test", `<button t-on-click="state.counter++">Click</button>`);
|
||||||
let owner = {
|
let owner = {
|
||||||
state: {
|
state: {
|
||||||
counter: 0,
|
counter: 0
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
const node = renderToDOM(qweb, "test", owner, { handlers: [] });
|
const node = renderToDOM(qweb, "test", owner, { handlers: [] });
|
||||||
expect(owner.state.counter).toBe(0);
|
expect(owner.state.counter).toBe(0);
|
||||||
@@ -1058,8 +1058,10 @@ describe("t-on", () => {
|
|||||||
let owner = {
|
let owner = {
|
||||||
state: {
|
state: {
|
||||||
counter: 0,
|
counter: 0,
|
||||||
incrementCounter: (inc) => { owner.state.counter += inc; },
|
incrementCounter: inc => {
|
||||||
},
|
owner.state.counter += inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const node = renderToDOM(qweb, "test", owner, { handlers: [] });
|
const node = renderToDOM(qweb, "test", owner, { handlers: [] });
|
||||||
expect(owner.state.counter).toBe(0);
|
expect(owner.state.counter).toBe(0);
|
||||||
@@ -1223,7 +1225,7 @@ describe("t-on", () => {
|
|||||||
);
|
);
|
||||||
const node = renderToDOM(qweb, "test", {}, { handlers: [] });
|
const node = renderToDOM(qweb, "test", {}, { handlers: [] });
|
||||||
|
|
||||||
node.addEventListener('click', (e) => {
|
node.addEventListener("click", e => {
|
||||||
expect(e.defaultPrevented).toBe(true);
|
expect(e.defaultPrevented).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user