mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+27
-33
@@ -337,15 +337,14 @@ This is the opposite method of `mounted`.
|
|||||||
|
|
||||||
### Composition
|
### Composition
|
||||||
|
|
||||||
The example above shows a QWeb template with a `t-on-click` directive. Widget
|
The example above shows a QWeb template with a sub component. In a template,
|
||||||
templates are standard [QWeb](qweb.md) templates, but with an extra directive:
|
components are declared with a tagname corresponding to the class name. It has
|
||||||
`t-widget`. With the `t-widget` directive, widget templates can declare sub
|
to be capitalized.
|
||||||
widgets:
|
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<span>some text</span>
|
<span>some text</span>
|
||||||
<t t-widget="MyWidget" info="13"/>
|
<MyWidget info="13" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -357,22 +356,18 @@ class ParentWidget extends owl.Component {
|
|||||||
```
|
```
|
||||||
|
|
||||||
In this example, the `ParentWidget`'s template creates a widget `MyWidget` just
|
In this example, the `ParentWidget`'s template creates a widget `MyWidget` just
|
||||||
after the span. The `info` key will be added to the subwidget's props. Each
|
after the span. The `info` key will be added to the subwidget's `props`. Each
|
||||||
props is a string which represents a javascript (QWeb) expression, so it is
|
`props` is a string which represents a javascript (QWeb) expression, so it is
|
||||||
dynamic. If it is necessary to give a string, this can be done by quoting it:
|
dynamic. If it is necessary to give a string, this can be done by quoting it:
|
||||||
`someString="'somevalue'"`. See the
|
`someString="'somevalue'"`.
|
||||||
[QWeb](qweb.md) documentation for more information on the `t-widget` directive.
|
|
||||||
|
|
||||||
Note that the rendering context for the template is the widget itself. This means
|
Note that the rendering context for the template is the widget itself. This means
|
||||||
that the template can access `state`, `props`, `env`, or any methods defined in the widget.
|
that the template can access `state`, `props`, `env`, or any methods defined in the widget.
|
||||||
|
|
||||||
The `t-widget` directive is the key to a declarative component
|
|
||||||
system. It allows a template to define where and how a sub widget is created
|
|
||||||
and/or updated. For example:
|
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<t t-widget="ChildWidget" count="state.val"/>
|
<ChildWidget count="state.val" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -397,12 +392,11 @@ the subwidget will also be updated automatically.
|
|||||||
Note that there are some restrictions on prop names: `class`, `style` and any
|
Note that there are some restrictions on prop names: `class`, `style` and any
|
||||||
string which starts with `t-` are not allowed.
|
string which starts with `t-` are not allowed.
|
||||||
|
|
||||||
The `t-widget` directive also accepts dynamic values with string interpolation
|
The `t-widget` directive can also be used to accept dynamic values with string interpolation (like the [`t-attf-`](qweb.md#dynamic-attributes) directive):
|
||||||
(like the [`t-attf-`](qweb.md#dynamic-attributes) directive):
|
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<t t-widget="ChildWidget{{id}}"/>
|
<t t-widget="ChildWidget{{id}}" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -419,7 +413,7 @@ root widget element.
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<t t-widget="MyWidget" class="someClass" style="font-weight:bold;" info="13"/>
|
<MyWidget class="someClass" style="font-weight:bold;" info="13" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -431,7 +425,7 @@ class that need to be removed. This is why we only support the explicit syntax
|
|||||||
with a class object:
|
with a class object:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<t t-widget="MyWidget" t-att-class="{a: state.flagA, b: state.flagB}" />
|
<MyWidget t-att-class="{a: state.flagA, b: state.flagB}" />
|
||||||
```
|
```
|
||||||
|
|
||||||
### Event Handling
|
### Event Handling
|
||||||
@@ -463,7 +457,7 @@ event.
|
|||||||
A _business_ DOM event is triggered by a call to `trigger` on a component.
|
A _business_ DOM event is triggered by a call to `trigger` on a component.
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<t t-widget="MyWidget" t-on-menu-loaded="someMethod"/>
|
<MyWidget t-on-menu-loaded="someMethod" />
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -538,8 +532,8 @@ class Form extends owl.Component {
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div>
|
<div>
|
||||||
<input t-on-input="_updateInputValue"/>
|
<input t-on-input="_updateInputValue" />
|
||||||
<span t-esc="state.text"/>
|
<span t-esc="state.text" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -559,8 +553,8 @@ class Form extends owl.Component {
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div>
|
<div>
|
||||||
<input t-model="text"/>
|
<input t-model="text" />
|
||||||
<span t-esc="state.text"/>
|
<span t-esc="state.text" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -586,7 +580,7 @@ The `t-model` directive works with `<input>`, `<input type="checkbox">`,
|
|||||||
<label for="red">Red</label>
|
<label for="red">Red</label>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<input type="radio" name="color" id="blue" value="blue" t-model="color"/>
|
<input type="radio" name="color" id="blue" value="blue" t-model="color" />
|
||||||
<label for="blue">Blue</label>
|
<label for="blue">Blue</label>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -604,7 +598,7 @@ Like event handling, the `t-model` directive accepts some modifiers:
|
|||||||
For example:
|
For example:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<input t-model.lazy="someVal"/>
|
<input t-model.lazy="someVal" />
|
||||||
```
|
```
|
||||||
|
|
||||||
These modifiers can be combined. For instance, `t-model.lazy.number` will only
|
These modifiers can be combined. For instance, `t-model.lazy.number` will only
|
||||||
@@ -627,7 +621,7 @@ There are three main use cases:
|
|||||||
|
|
||||||
```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>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -836,7 +830,7 @@ Like the `t-on` directive, it can work either on a DOM node, or on a component:
|
|||||||
```xml
|
```xml
|
||||||
<div>
|
<div>
|
||||||
<div t-ref="someDiv"/>
|
<div t-ref="someDiv"/>
|
||||||
<t t-widget="SubWidget" t-ref="someWidget"/>
|
<SubWidget t-ref="someWidget"/>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -894,14 +888,14 @@ Slots are defined by the caller, with the `t-set` directive:
|
|||||||
```xml
|
```xml
|
||||||
<div t-name="SomeWidget">
|
<div t-name="SomeWidget">
|
||||||
<div>some widget</div>
|
<div>some widget</div>
|
||||||
<t t-widget="Dialog" title="Some Dialog">
|
<Dialog title="Some Dialog">
|
||||||
<t t-set="content">
|
<t t-set="content">
|
||||||
<div>hey</div>
|
<div>hey</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-set="footer">
|
<t t-set="footer">
|
||||||
<button t-on-click="doSomething">ok</button>
|
<button t-on-click="doSomething">ok</button>
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -933,9 +927,9 @@ be considered the `default` slot. For example:
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<t t-widget="Child">
|
<Child>
|
||||||
<span>some content</span>
|
<span>some content</span>
|
||||||
</t>
|
</Child>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div t-name="Child">
|
<div t-name="Child">
|
||||||
@@ -979,7 +973,7 @@ Here are a few tips on how to work with asynchronous widgets:
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<t t-widget="SyncChild"/>
|
<SyncChild />
|
||||||
<t t-widget="AsyncChild" t-asyncroot="1"/>
|
<AsyncChild t-asyncroot="1"/>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|||||||
+1
-1
@@ -132,7 +132,7 @@ It's API is quite simple:
|
|||||||
...
|
...
|
||||||
|
|
||||||
class ParentWidget extends owl.Component { ... }
|
class ParentWidget extends owl.Component { ... }
|
||||||
qweb.addTemplate("ParentWidget", "<div><t t-widget='Dialog'/></div>");
|
qweb.addTemplate("ParentWidget", "<div><Dialog/></div>");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|||||||
@@ -346,6 +346,13 @@ export class QWeb {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const firstLetter = node.tagName[0];
|
||||||
|
if (firstLetter === firstLetter.toUpperCase()) {
|
||||||
|
// this is a component, we modify in place the xml document to change
|
||||||
|
// <SomeComponent ... /> to <t t-widget="SomeComponent" ... />
|
||||||
|
node.setAttribute('t-widget', node.tagName);
|
||||||
|
node.nodeValue = 't';
|
||||||
|
}
|
||||||
const attributes = (<Element>node).attributes;
|
const attributes = (<Element>node).attributes;
|
||||||
|
|
||||||
const validDirectives: {
|
const validDirectives: {
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ const T_WIDGET_MODS_CODE = Object.assign({}, MODS_CODE, {
|
|||||||
* explanation of the code generated by the t-widget directive for the following
|
* explanation of the code generated by the t-widget directive for the following
|
||||||
* situation:
|
* situation:
|
||||||
* ```xml
|
* ```xml
|
||||||
* <t t-widget="child"
|
* <Child
|
||||||
* t-key="'somestring'"
|
* t-key="'somestring'"
|
||||||
* flag="state.flag"
|
* flag="state.flag"
|
||||||
* t-transition="fade"/>
|
* t-transition="fade"/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`animations t-transition combined with t-widget 1`] = `
|
exports[`animations t-transition combined with component 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
let utils = this.utils;
|
let utils = this.utils;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`async rendering delayed t-widget with t-asyncroot directive 1`] = `
|
exports[`async rendering delayed component with t-asyncroot directive 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
let utils = this.utils;
|
let utils = this.utils;
|
||||||
@@ -81,7 +81,7 @@ exports[`async rendering delayed t-widget with t-asyncroot directive 1`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`async rendering fast t-widget with t-asyncroot directive 1`] = `
|
exports[`async rendering fast component with t-asyncroot directive 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
let utils = this.utils;
|
let utils = this.utils;
|
||||||
@@ -650,7 +650,7 @@ exports[`other directives with t-widget t-on with prevent and self modifiers (or
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!w4) {
|
if (!w4) {
|
||||||
let widgetKey4 = \`child\`;
|
let widgetKey4 = \`Child\`;
|
||||||
let W4 = context.widgets && context.widgets[widgetKey4] || QWeb.widgets[widgetKey4];
|
let W4 = context.widgets && context.widgets[widgetKey4] || QWeb.widgets[widgetKey4];
|
||||||
if (!W4) {throw new Error('Cannot find the definition of widget \\"' + widgetKey4 + '\\"')}
|
if (!W4) {throw new Error('Cannot find the definition of widget \\"' + widgetKey4 + '\\"')}
|
||||||
w4 = new W4(owner, props4);
|
w4 = new W4(owner, props4);
|
||||||
|
|||||||
@@ -170,12 +170,12 @@ describe("animations", () => {
|
|||||||
expect(spanNode.className).toBe("");
|
expect(spanNode.className).toBe("");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-transition combined with t-widget", async () => {
|
test("t-transition combined with component", async () => {
|
||||||
expect.assertions(5);
|
expect.assertions(5);
|
||||||
|
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
`<div><t t-widget="Child" t-transition="chimay"/></div>`
|
`<div><Child t-transition="chimay"/></div>`
|
||||||
);
|
);
|
||||||
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
|
|||||||
+65
-50
@@ -468,7 +468,7 @@ describe("lifecycle hooks", () => {
|
|||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<div t-if="state.flag">
|
<div t-if="state.flag">
|
||||||
<t t-widget="ChildWidget" n="state.n"/>
|
<ChildWidget n="state.n"/>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -549,7 +549,7 @@ describe("lifecycle hooks", () => {
|
|||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
'<span><t t-widget="Child" n="state.n"/></span>'
|
'<span><Child n="state.n"/></span>'
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
state = { n: 1 };
|
state = { n: 1 };
|
||||||
@@ -601,7 +601,7 @@ describe("lifecycle hooks", () => {
|
|||||||
|
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
'<div><t t-widget="Child" a="state.a"/></div>'
|
'<div><Child a="state.a"/></div>'
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
state = { a: 1 };
|
state = { a: 1 };
|
||||||
@@ -644,7 +644,7 @@ describe("lifecycle hooks", () => {
|
|||||||
let shouldUpdate = false;
|
let shouldUpdate = false;
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
`<div><t t-widget="Child" val="state.val"/></div>`
|
`<div><Child val="state.val"/></div>`
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
state = { val: 42 };
|
state = { val: 42 };
|
||||||
@@ -889,11 +889,26 @@ describe("composition", () => {
|
|||||||
delete QWeb.widgets["WidgetB"];
|
delete QWeb.widgets["WidgetB"];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("can define widgets in template without t-widget", async () => {
|
||||||
|
env.qweb.addTemplates(`
|
||||||
|
<templates>
|
||||||
|
<div t-name="P"><C a="1"/></div>
|
||||||
|
<span t-name="C"><t t-esc="props.a"/></span>
|
||||||
|
</templates>`);
|
||||||
|
class C extends Widget {}
|
||||||
|
class P extends Widget {
|
||||||
|
widgets = {C};
|
||||||
|
}
|
||||||
|
const parent = new P(env);
|
||||||
|
await parent.mount(fixture);
|
||||||
|
expect(fixture.innerHTML).toBe("<div><span>1</span></div>");
|
||||||
|
});
|
||||||
|
|
||||||
test("throw a nice error if it cannot find widget", async () => {
|
test("throw a nice error if it cannot find widget", async () => {
|
||||||
expect.assertions(1);
|
expect.assertions(1);
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
`<div><t t-widget="SomeMispelledWidget"/></div>`
|
`<div><SomeMispelledWidget /></div>`
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
widgets = { SomeWidget: Widget };
|
widgets = { SomeWidget: Widget };
|
||||||
@@ -1074,11 +1089,11 @@ describe("composition", () => {
|
|||||||
test("sub widgets are destroyed if no longer in dom, then recreated", async () => {
|
test("sub widgets are destroyed if no longer in dom, then recreated", async () => {
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"ParentWidget",
|
"ParentWidget",
|
||||||
`<div><t t-if="state.ok"><t t-widget="counter"/></t></div>`
|
`<div><t t-if="state.ok"><Counter /></t></div>`
|
||||||
);
|
);
|
||||||
class ParentWidget extends Widget {
|
class ParentWidget extends Widget {
|
||||||
state = { ok: true };
|
state = { ok: true };
|
||||||
widgets = { counter: Counter };
|
widgets = { Counter };
|
||||||
}
|
}
|
||||||
const widget = new ParentWidget(env);
|
const widget = new ParentWidget(env);
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
@@ -1102,11 +1117,11 @@ describe("composition", () => {
|
|||||||
test("sub widgets with t-keepalive are not destroyed if no longer in dom", async () => {
|
test("sub widgets with t-keepalive are not destroyed if no longer in dom", async () => {
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"ParentWidget",
|
"ParentWidget",
|
||||||
`<div><t t-if="state.ok"><t t-widget="counter" t-keepalive="1"/></t></div>`
|
`<div><t t-if="state.ok"><Counter t-keepalive="1"/></t></div>`
|
||||||
);
|
);
|
||||||
class ParentWidget extends Widget {
|
class ParentWidget extends Widget {
|
||||||
state = { ok: true };
|
state = { ok: true };
|
||||||
widgets = { counter: Counter };
|
widgets = { Counter };
|
||||||
}
|
}
|
||||||
const widget = new ParentWidget(env);
|
const widget = new ParentWidget(env);
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
@@ -1135,7 +1150,7 @@ describe("composition", () => {
|
|||||||
test("sub widgets dom state with t-keepalive is preserved", async () => {
|
test("sub widgets dom state with t-keepalive is preserved", async () => {
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"ParentWidget",
|
"ParentWidget",
|
||||||
`<div><t t-if="state.ok"><t t-widget="InputWidget" t-keepalive="1"/></t></div>`
|
`<div><t t-if="state.ok"><InputWidget t-keepalive="1"/></t></div>`
|
||||||
);
|
);
|
||||||
class ParentWidget extends Widget {
|
class ParentWidget extends Widget {
|
||||||
state = { ok: true };
|
state = { ok: true };
|
||||||
@@ -1163,7 +1178,7 @@ describe("composition", () => {
|
|||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<t t-if="state.ok"><t t-widget="ChildWidget" t-ref="child" t-keepalive="1"/></t>
|
<t t-if="state.ok"><ChildWidget t-ref="child" t-keepalive="1"/></t>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="ChildWidget">Hello</span>
|
<span t-name="ChildWidget">Hello</span>
|
||||||
</templates>`);
|
</templates>`);
|
||||||
@@ -1275,7 +1290,7 @@ describe("composition", () => {
|
|||||||
`<div>
|
`<div>
|
||||||
<h1 t-if="state.flag">hey</h1>
|
<h1 t-if="state.flag">hey</h1>
|
||||||
<h2 t-else="1">noo</h2>
|
<h2 t-else="1">noo</h2>
|
||||||
<span><t t-widget="ChildWidget"/></span>
|
<span><ChildWidget/></span>
|
||||||
<t t-if="state.flag"><span>test</span></t>
|
<t t-if="state.flag"><span>test</span></t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -1723,18 +1738,18 @@ describe("other directives with t-widget", () => {
|
|||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="ParentWidget">
|
<div t-name="ParentWidget">
|
||||||
<t t-widget="child" t-on-ev.prevent.self="onEv"/>
|
<Child t-on-ev.prevent.self="onEv"/>
|
||||||
</div>
|
</div>
|
||||||
<div t-name="Child"><t t-widget="child"/></div>
|
<div t-name="Child"><GrandChild/></div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
const steps: boolean[] = [];
|
const steps: boolean[] = [];
|
||||||
class ParentWidget extends Widget {
|
class ParentWidget extends Widget {
|
||||||
widgets = { child: Child };
|
widgets = { Child };
|
||||||
onEv() {}
|
onEv() {}
|
||||||
}
|
}
|
||||||
class Child extends Widget {
|
class Child extends Widget {
|
||||||
widgets = { child: GrandChild };
|
widgets = { GrandChild };
|
||||||
}
|
}
|
||||||
class GrandChild extends Widget {}
|
class GrandChild extends Widget {}
|
||||||
const widget = new ParentWidget(env);
|
const widget = new ParentWidget(env);
|
||||||
@@ -1962,7 +1977,7 @@ describe("random stuff/miscellaneous", () => {
|
|||||||
steps.push(`${this.name}:destroy`);
|
steps.push(`${this.name}:destroy`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
env.qweb.addTemplate("A", `<div>A<t t-widget="B"/><t t-widget="C"/></div>`);
|
env.qweb.addTemplate("A", `<div>A<B /><C /></div>`);
|
||||||
class A extends TestWidget {
|
class A extends TestWidget {
|
||||||
widgets = { B, C };
|
widgets = { B, C };
|
||||||
name = "A";
|
name = "A";
|
||||||
@@ -1978,9 +1993,9 @@ describe("random stuff/miscellaneous", () => {
|
|||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"C",
|
"C",
|
||||||
`
|
`
|
||||||
<div>C<t t-widget="D"/>
|
<div>C<D />
|
||||||
<t t-if="state.flag" t-widget="E"/>
|
<E t-if="state.flag" />
|
||||||
<t t-else="!state.flag" t-widget="F"/>
|
<F t-else="!state.flag" />
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class C extends TestWidget {
|
class C extends TestWidget {
|
||||||
@@ -2102,7 +2117,7 @@ describe("async rendering", () => {
|
|||||||
let n = 0;
|
let n = 0;
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"W",
|
"W",
|
||||||
`<div><t t-if="state.val > 1"><t t-widget="Child" val="state.val"/></t></div>`
|
`<div><t t-if="state.val > 1"><Child val="state.val"/></t></div>`
|
||||||
);
|
);
|
||||||
class W extends Widget {
|
class W extends Widget {
|
||||||
widgets = { Child };
|
widgets = { Child };
|
||||||
@@ -2156,8 +2171,8 @@ describe("async rendering", () => {
|
|||||||
"Parent",
|
"Parent",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.flagA"><t t-widget="ChildA"/></t>
|
<t t-if="state.flagA"><ChildA /></t>
|
||||||
<t t-if="state.flagB"><t t-widget="ChildB"/></t>
|
<t t-if="state.flagB"><ChildB /></t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
@@ -2203,8 +2218,8 @@ describe("async rendering", () => {
|
|||||||
"Parent",
|
"Parent",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-widget="ChildA" val="state.valA"/>
|
<ChildA val="state.valA"/>
|
||||||
<t t-if="state.flagB"><t t-widget="ChildB" val="state.valB"/></t>
|
<t t-if="state.flagB"><ChildB val="state.valB"/></t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
@@ -2254,7 +2269,7 @@ describe("async rendering", () => {
|
|||||||
<ul>
|
<ul>
|
||||||
<t t-foreach="items" t-as="item">
|
<t t-foreach="items" t-as="item">
|
||||||
<li t-key="'li_'+item">
|
<li t-key="'li_'+item">
|
||||||
<t t-widget="Child" item="item"/>
|
<Child item="item"/>
|
||||||
</li>
|
</li>
|
||||||
</t>
|
</t>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -2271,7 +2286,7 @@ describe("async rendering", () => {
|
|||||||
test("properly behave when destroyed/unmounted while rendering ", async () => {
|
test("properly behave when destroyed/unmounted while rendering ", async () => {
|
||||||
let def = Promise.resolve();
|
let def = Promise.resolve();
|
||||||
|
|
||||||
env.qweb.addTemplate("Child", `<div><t t-widget="SubChild"/></div>`);
|
env.qweb.addTemplate("Child", `<div><SubChild /></div>`);
|
||||||
class Child extends Widget {
|
class Child extends Widget {
|
||||||
widgets = { SubChild };
|
widgets = { SubChild };
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -2298,7 +2313,7 @@ describe("async rendering", () => {
|
|||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
`
|
`
|
||||||
<div><t t-if="state.flag"><t t-widget="Child" val="state.val"/></t></div>`
|
<div><t t-if="state.flag"><Child val="state.val"/></t></div>`
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
widgets = { Child };
|
widgets = { Child };
|
||||||
@@ -2331,8 +2346,8 @@ describe("async rendering", () => {
|
|||||||
<span t-name="ChildB">b<t t-esc="props.val"/></span>
|
<span t-name="ChildB">b<t t-esc="props.val"/></span>
|
||||||
<span t-name="Parent">
|
<span t-name="Parent">
|
||||||
<t t-if="state.flag">
|
<t t-if="state.flag">
|
||||||
<t t-widget="ChildA" val="state.valA"/>
|
<ChildA val="state.valA"/>
|
||||||
<t t-widget="ChildB" val="state.valB"/>
|
<ChildB val="state.valB"/>
|
||||||
</t>
|
</t>
|
||||||
</span>
|
</span>
|
||||||
</templates>
|
</templates>
|
||||||
@@ -2368,14 +2383,14 @@ describe("async rendering", () => {
|
|||||||
expect(destroyCount).toBe(0);
|
expect(destroyCount).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("delayed t-widget with t-asyncroot directive", async () => {
|
test("delayed component with t-asyncroot directive", async () => {
|
||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<button t-on-click="updateApp">Update App State</button>
|
<button t-on-click="updateApp">Update App State</button>
|
||||||
<div class="children">
|
<div class="children">
|
||||||
<t t-widget="Child" val="state.val"/>
|
<Child val="state.val"/>
|
||||||
<t t-widget="AsyncChild" t-asyncroot="1" val="state.val"/>
|
<AsyncChild t-asyncroot="1" val="state.val"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="Child"><t t-esc="props.val"/></span>
|
<span t-name="Child"><t t-esc="props.val"/></span>
|
||||||
@@ -2423,14 +2438,14 @@ describe("async rendering", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("fast t-widget with t-asyncroot directive", async () => {
|
test("fast component with t-asyncroot directive", async () => {
|
||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<button t-on-click="updateApp">Update App State</button>
|
<button t-on-click="updateApp">Update App State</button>
|
||||||
<div class="children">
|
<div class="children">
|
||||||
<t t-widget="Child" t-asyncroot="1" val="state.val"/>
|
<Child t-asyncroot="1" val="state.val"/>
|
||||||
<t t-widget="AsyncChild" val="state.val"/>
|
<AsyncChild val="state.val"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="Child"><t t-esc="props.val"/></span>
|
<span t-name="Child"><t t-esc="props.val"/></span>
|
||||||
@@ -2484,8 +2499,8 @@ describe("async rendering", () => {
|
|||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<button t-on-click="updateApp">Update App State</button>
|
<button t-on-click="updateApp">Update App State</button>
|
||||||
<div class="children">
|
<div class="children">
|
||||||
<t t-widget="Child" val="state.val"/>
|
<Child val="state.val"/>
|
||||||
<t t-widget="AsyncChild" t-asyncroot="1" val="state.val"/>
|
<AsyncChild t-asyncroot="1" val="state.val"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="Child" t-on-click="increment">
|
<span t-name="Child" t-on-click="increment">
|
||||||
@@ -2617,9 +2632,9 @@ describe("updating environment", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("updating parent env does modify child env, part 2", async () => {
|
test("updating parent env does modify child env, part 2", async () => {
|
||||||
env.qweb.addTemplate("ParentWidget", `<div><t t-widget="child"/></div>`);
|
env.qweb.addTemplate("ParentWidget", `<div><Child/></div>`);
|
||||||
class ParentWidget extends Widget {
|
class ParentWidget extends Widget {
|
||||||
widgets = { child: Widget };
|
widgets = { Child: Widget };
|
||||||
}
|
}
|
||||||
const parent = new ParentWidget(env);
|
const parent = new ParentWidget(env);
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
@@ -2642,7 +2657,7 @@ describe("updating environment", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("updating env force rerendering children", async () => {
|
test("updating env force rerendering children", async () => {
|
||||||
env.qweb.addTemplate("Parent", `<div><t t-widget="Child"/></div>`);
|
env.qweb.addTemplate("Parent", `<div><Child /></div>`);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
widgets = { Child };
|
widgets = { Child };
|
||||||
}
|
}
|
||||||
@@ -2680,7 +2695,7 @@ describe("widget and observable state", () => {
|
|||||||
expect.assertions(1);
|
expect.assertions(1);
|
||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"Parent",
|
"Parent",
|
||||||
`<div><t t-widget="Child" obj="state.obj"/></div>`
|
`<div><Child obj="state.obj"/></div>`
|
||||||
);
|
);
|
||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
state = { obj: { coffee: 1 } };
|
state = { obj: { coffee: 1 } };
|
||||||
@@ -2822,10 +2837,10 @@ describe("t-slot directive", () => {
|
|||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<t t-widget="Dialog">
|
<Dialog>
|
||||||
<t t-set="header"><span>header</span></t>
|
<t t-set="header"><span>header</span></t>
|
||||||
<t t-set="footer"><span>footer</span></t>
|
<t t-set="footer"><span>footer</span></t>
|
||||||
</t>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
<div t-name="Dialog">
|
<div t-name="Dialog">
|
||||||
<div><t t-slot="header"/></div>
|
<div><t t-slot="header"/></div>
|
||||||
@@ -2852,9 +2867,9 @@ describe("t-slot directive", () => {
|
|||||||
<templates>
|
<templates>
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<span class="counter"><t t-esc="state.val"/></span>
|
<span class="counter"><t t-esc="state.val"/></span>
|
||||||
<t t-widget="Dialog">
|
<Dialog>
|
||||||
<t t-set="footer"><button t-on-click="doSomething">do something</button></t>
|
<t t-set="footer"><button t-on-click="doSomething">do something</button></t>
|
||||||
</t>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="Dialog"><t t-slot="footer"/></span>
|
<span t-name="Dialog"><t t-slot="footer"/></span>
|
||||||
</templates>
|
</templates>
|
||||||
@@ -2887,9 +2902,9 @@ describe("t-slot directive", () => {
|
|||||||
<templates>
|
<templates>
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<span class="counter"><t t-esc="state.val"/></span>
|
<span class="counter"><t t-esc="state.val"/></span>
|
||||||
<t t-widget="Dialog">
|
<Dialog>
|
||||||
<t t-set="footer"><button t-ref="myButton" t-on-click="doSomething">do something</button></t>
|
<t t-set="footer"><button t-ref="myButton" t-on-click="doSomething">do something</button></t>
|
||||||
</t>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="Dialog"><t t-slot="footer"/></span>
|
<span t-name="Dialog"><t t-slot="footer"/></span>
|
||||||
</templates>
|
</templates>
|
||||||
@@ -3153,9 +3168,9 @@ describe("t-model directive", () => {
|
|||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="Parent">
|
<div t-name="Parent">
|
||||||
<t t-widget="Dialog">
|
<Dialog>
|
||||||
<span>sts rocks</span>
|
<span>sts rocks</span>
|
||||||
</t>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
<div t-name="Dialog"><t t-slot="default"/></div>
|
<div t-name="Dialog"><t t-slot="default"/></div>
|
||||||
</templates>
|
</templates>
|
||||||
|
|||||||
+11
-11
@@ -534,8 +534,8 @@ describe("connecting a component to store", () => {
|
|||||||
"App",
|
"App",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="props.todos" t-as="todo" t-key="todo">
|
<t t-foreach="props.todos" t-as="todo" >
|
||||||
<t t-widget="Todo" msg="todo.msg"/>
|
<Todo msg="todo.msg" t-key="todo"/>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -624,8 +624,8 @@ describe("connecting a component to store", () => {
|
|||||||
env.qweb.addTemplates(`
|
env.qweb.addTemplates(`
|
||||||
<templates>
|
<templates>
|
||||||
<div t-name="App">
|
<div t-name="App">
|
||||||
<t t-foreach="props.todos" t-as="todo" t-key="todo">
|
<t t-foreach="props.todos" t-as="todo">
|
||||||
<t t-widget="Todo" msg="todo.msg"/>
|
<Todo msg="todo.msg" t-key="todo" />
|
||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
<span t-name="Todo"><t t-esc="props.msg"/></span>
|
<span t-name="Todo"><t t-esc="props.msg"/></span>
|
||||||
@@ -734,7 +734,7 @@ describe("connecting a component to store", () => {
|
|||||||
"TodoList",
|
"TodoList",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-foreach="props.todos" t-as="todo">
|
<t t-foreach="props.todos" t-as="todo">
|
||||||
<t t-widget="ConnectedTodo" id="todo.id"/>
|
<ConnectedTodo id="todo.id" t-key="todo.id"/>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -801,7 +801,7 @@ describe("connecting a component to store", () => {
|
|||||||
"TodoList",
|
"TodoList",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-foreach="props.todos" t-as="todo">
|
<t t-foreach="props.todos" t-as="todo">
|
||||||
<t t-widget="ConnectedTodo" id="todo.id"/>
|
<ConnectedTodo id="todo.id" t-key="todo.id"/>
|
||||||
</t>
|
</t>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
@@ -839,7 +839,7 @@ describe("connecting a component to store", () => {
|
|||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"App",
|
"App",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-widget="ConnectedBeer" id="state.beerId"/>
|
<ConnectedBeer id="state.beerId"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class App extends Component<any, any, any> {
|
class App extends Component<any, any, any> {
|
||||||
@@ -923,8 +923,8 @@ describe("connecting a component to store", () => {
|
|||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"App",
|
"App",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-widget="ConnectedBeer" id="state.beerId"/>
|
<ConnectedBeer id="state.beerId"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class App extends Component<any, any, any> {
|
class App extends Component<any, any, any> {
|
||||||
widgets = { ConnectedBeer };
|
widgets = { ConnectedBeer };
|
||||||
@@ -995,7 +995,7 @@ describe("connecting a component to store", () => {
|
|||||||
env.qweb.addTemplate(
|
env.qweb.addTemplate(
|
||||||
"App",
|
"App",
|
||||||
`<div>
|
`<div>
|
||||||
<t t-widget="ConnectedBeer" id="state.beerId"/>
|
<ConnectedBeer id="state.beerId"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class App extends Component<any, any, any> {
|
class App extends Component<any, any, any> {
|
||||||
@@ -1074,7 +1074,7 @@ describe("connecting a component to store", () => {
|
|||||||
"Parent",
|
"Parent",
|
||||||
`
|
`
|
||||||
<div>
|
<div>
|
||||||
<t t-widget="Child" key="props.current"/>
|
<Child key="props.current"/>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|||||||
+19
-19
@@ -26,8 +26,8 @@ const COMPONENTS_XML = `<templates>
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div t-name="App">
|
<div t-name="App">
|
||||||
<t t-widget="Counter"/>
|
<Counter />
|
||||||
<t t-widget="Counter"/>
|
<Counter />
|
||||||
</div>
|
</div>
|
||||||
</templates>`;
|
</templates>`;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ const ANIMATION_XML = `<templates>
|
|||||||
<div class="demo">
|
<div class="demo">
|
||||||
<button t-on-click="toggle('widgetFlag')">Toggle widget</button>
|
<button t-on-click="toggle('widgetFlag')">Toggle widget</button>
|
||||||
<div>
|
<div>
|
||||||
<t t-widget="Counter" t-if="state.widgetFlag" t-transition="fade"/>
|
<Counter t-if="state.widgetFlag" t-transition="fade"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ const ANIMATION_XML = `<templates>
|
|||||||
<button t-on-click="addNumber">Add a number</button>
|
<button t-on-click="addNumber">Add a number</button>
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="state.numbers" t-as="n">
|
<t t-foreach="state.numbers" t-as="n">
|
||||||
<span t-transition="fade" class="numberspan"><t t-esc="n"/></span>
|
<span t-transition="fade" class="numberspan" t-key="n"><t t-esc="n"/></span>
|
||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -236,7 +236,7 @@ const LIFECYCLE_DEMO_XML = `<templates>
|
|||||||
<button t-on-click="increment">Increment Parent State</button>
|
<button t-on-click="increment">Increment Parent State</button>
|
||||||
<button t-on-click="toggleSubWidget">Toggle SubWidget</button>
|
<button t-on-click="toggleSubWidget">Toggle SubWidget</button>
|
||||||
<div t-if="state.flag">
|
<div t-if="state.flag">
|
||||||
<t t-widget="DemoWidget" n="state.n"/>
|
<DemoWidget n="state.n"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</templates>`;
|
</templates>`;
|
||||||
@@ -483,7 +483,7 @@ const TODO_APP_STORE_XML = `<templates>
|
|||||||
<label for="toggle-all"></label>
|
<label for="toggle-all"></label>
|
||||||
<ul class="todo-list">
|
<ul class="todo-list">
|
||||||
<t t-foreach="visibleTodos" t-as="todo">
|
<t t-foreach="visibleTodos" t-as="todo">
|
||||||
<t t-widget="TodoItem" t-key="todo.id" id="todo.id" completed="todo.completed" title="todo.title"/>
|
<TodoItem t-key="todo.id" id="todo.id" completed="todo.completed" title="todo.title"/>
|
||||||
</t>
|
</t>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
@@ -995,17 +995,17 @@ const RESPONSIVE_XML = `<templates>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div t-name="App" class="app" t-att-class="{mobile: env.isMobile, desktop: !env.isMobile}">
|
<div t-name="App" class="app" t-att-class="{mobile: env.isMobile, desktop: !env.isMobile}">
|
||||||
<t t-widget="Navbar"/>
|
<Navbar/>
|
||||||
<t t-widget="ControlPanel"/>
|
<ControlPanel/>
|
||||||
<div class="content-wrapper" t-if="!env.isMobile">
|
<div class="content-wrapper" t-if="!env.isMobile">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<t t-widget="FormView"/>
|
<FormView />
|
||||||
<t t-widget="Chatter"/>
|
<Chatter />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<t t-else="1">
|
<t t-else="1">
|
||||||
<t t-widget="FormView"/>
|
<FormView />
|
||||||
<t t-widget="Chatter"/>
|
<Chatter />
|
||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
@@ -1128,17 +1128,17 @@ const SLOTS_XML = `<templates>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div t-name="App" class="main">
|
<div t-name="App" class="main">
|
||||||
<t t-widget="Card" title="'Title card A'">
|
<Card title="'Title card A'">
|
||||||
<t t-set="content">Content of card 1... [<t t-esc="state.a"/>]</t>
|
<t t-set="content">Content of card 1... [<t t-esc="state.a"/>]</t>
|
||||||
<t t-set="footer"><button t-on-click="inc('a', 1)">Increment A</button></t>
|
<t t-set="footer"><button t-on-click="inc('a', 1)">Increment A</button></t>
|
||||||
</t>
|
</Card>
|
||||||
<t t-widget="Card" title="'Title card B'">
|
<Card title="'Title card B'">
|
||||||
<div t-set="content">
|
<div t-set="content">
|
||||||
<div>Card 2... [<t t-esc="state.b"/>]</div>
|
<div>Card 2... [<t t-esc="state.b"/>]</div>
|
||||||
<t t-widget="Counter"/>
|
<Counter />
|
||||||
</div>
|
</div>
|
||||||
<t t-set="footer"><button t-on-click="inc('b', -1)">Decrement B</button></t>
|
<t t-set="footer"><button t-on-click="inc('b', -1)">Decrement B</button></t>
|
||||||
</t>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</templates>`;
|
</templates>`;
|
||||||
|
|
||||||
@@ -1226,8 +1226,8 @@ app.mount(document.body);
|
|||||||
const ASYNC_COMPONENTS_XML = `<templates>
|
const ASYNC_COMPONENTS_XML = `<templates>
|
||||||
<div t-name="App" class="app">
|
<div t-name="App" class="app">
|
||||||
<button t-on-click="increment">Increment</button>
|
<button t-on-click="increment">Increment</button>
|
||||||
<t t-widget="SlowWidget" value="state.value"/>
|
<SlowWidget value="state.value"/>
|
||||||
<t t-widget="NotificationList" t-asyncroot="1" notifications="state.notifs"/>
|
<NotificationList t-asyncroot="1" notifications="state.notifs"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div t-name="SlowWidget" class="value" >
|
<div t-name="SlowWidget" class="value" >
|
||||||
|
|||||||
@@ -24,14 +24,14 @@
|
|||||||
<a class="btn flash" t-on-click="downloadCode" title="Download a Zip with this Code"><i class="fas fa-download"></i></a>
|
<a class="btn flash" t-on-click="downloadCode" title="Download a Zip with this Code"><i class="fas fa-download"></i></a>
|
||||||
<a class="layout-selector flash" t-on-click="toggleLayout" title="Toggle Layout"><i class="fas" t-att-class="state.splitLayout ? 'fa-toggle-on' : 'fa-toggle-off'"></i></a>
|
<a class="layout-selector flash" t-on-click="toggleLayout" title="Toggle Layout"><i class="fas" t-att-class="state.splitLayout ? 'fa-toggle-on' : 'fa-toggle-off'"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<t t-widget="TabbedEditor"
|
<TabbedEditor
|
||||||
js="state.js"
|
js="state.js"
|
||||||
css="!state.splitLayout and state.css"
|
css="!state.splitLayout and state.css"
|
||||||
xml="!state.splitLayout and state.js"
|
xml="!state.splitLayout and state.js"
|
||||||
t-att-style="topEditorStyle"/>
|
t-att-style="topEditorStyle"/>
|
||||||
<t t-if="state.splitLayout">
|
<t t-if="state.splitLayout">
|
||||||
<div class="separator horizontal"/>
|
<div class="separator horizontal"/>
|
||||||
<t t-widget="TabbedEditor" t-keepalive="1"
|
<TabbedEditor t-keepalive="1"
|
||||||
js="false"
|
js="false"
|
||||||
css="state.css"
|
css="state.css"
|
||||||
xml="state.xml"
|
xml="state.xml"
|
||||||
|
|||||||
Reference in New Issue
Block a user