mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
add t-ref directive
This commit is contained in:
@@ -48,4 +48,7 @@ Before even thinking about using this in a real scenario:
|
|||||||
- style is props? difference between props and attrs
|
- style is props? difference between props and attrs
|
||||||
- text node
|
- text node
|
||||||
- t-extend???
|
- t-extend???
|
||||||
- improve qweb generated code: do not assign object/array if no props/attrs/children
|
- improve qweb generated code: do not assign object/array if no props/attrs/children
|
||||||
|
- improve qweb gen code: when building a vnode, propagate a structure with
|
||||||
|
children/attrs/hooks, fill it properly by each directive, then and only
|
||||||
|
then create node with minimal code
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import Widget from "../../src/core/widget";
|
import Widget from "../../src/core/widget";
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
<div t-debug="1">
|
<div>
|
||||||
<button t-on-click="increment(-1)">-</button>
|
<button t-on-click="increment(-1)">-</button>
|
||||||
<span style="font-weight:bold">Value: <t t-esc="state.counter"/></span>
|
<span style="font-weight:bold">Value: <t t-esc="state.counter"/></span>
|
||||||
<button t-on-click="increment(1)">+</button>
|
<button t-on-click="increment(1)">+</button>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Widget from "../../src/core/widget";
|
|||||||
import Counter from "./Counter";
|
import Counter from "./Counter";
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
<div t-debug="1">
|
<div>
|
||||||
<span>Root Widget</span>
|
<span>Root Widget</span>
|
||||||
<button t-on-click="resetCounter">Reset</button>
|
<button t-on-click="resetCounter">Reset</button>
|
||||||
<button t-on-click="resetCounterAsync">Reset in 3s</button>
|
<button t-on-click="resetCounterAsync">Reset in 3s</button>
|
||||||
|
|||||||
+12
-1
@@ -100,6 +100,7 @@ export default class QWeb {
|
|||||||
ifDirective,
|
ifDirective,
|
||||||
callDirective,
|
callDirective,
|
||||||
onDirective,
|
onDirective,
|
||||||
|
refDirective,
|
||||||
widgetDirective
|
widgetDirective
|
||||||
].forEach(d => this.addDirective(d));
|
].forEach(d => this.addDirective(d));
|
||||||
}
|
}
|
||||||
@@ -653,6 +654,17 @@ const onDirective: Directive = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refDirective: Directive = {
|
||||||
|
name: "ref",
|
||||||
|
priority: 95,
|
||||||
|
atNodeCreation({ ctx, node, nodeID }) {
|
||||||
|
let ref = node.getAttribute("t-ref");
|
||||||
|
ctx.addLine(`p${ctx.parentNode}.hook = {
|
||||||
|
create: (_, n) => context.refs['${ref}'] = n.elm,
|
||||||
|
}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const widgetDirective: Directive = {
|
const widgetDirective: Directive = {
|
||||||
name: "widget",
|
name: "widget",
|
||||||
priority: 100,
|
priority: 100,
|
||||||
@@ -671,7 +683,6 @@ const widgetDirective: Directive = {
|
|||||||
);
|
);
|
||||||
ctx.addLine(`context._TEMP.push(def${defID})`);
|
ctx.addLine(`context._TEMP.push(def${defID})`);
|
||||||
|
|
||||||
// split into extra directive?
|
|
||||||
let ref = node.getAttribute("t-ref");
|
let ref = node.getAttribute("t-ref");
|
||||||
if (ref) {
|
if (ref) {
|
||||||
ctx.addLine(`context.refs['${ref}'] = _${widgetID}`);
|
ctx.addLine(`context.refs['${ref}'] = _${widgetID}`);
|
||||||
|
|||||||
+12
-1
@@ -69,7 +69,7 @@ describe("error handling", () => {
|
|||||||
|
|
||||||
test("template with text node and tag", () => {
|
test("template with text node and tag", () => {
|
||||||
const qweb = new QWeb();
|
const qweb = new QWeb();
|
||||||
qweb.addTemplate("test", `<t t-debug="1">text<span>other node</span></t>`);
|
qweb.addTemplate("test", `<t>text<span>other node</span></t>`);
|
||||||
|
|
||||||
expect(() => renderToString(qweb, "test")).toThrow(
|
expect(() => renderToString(qweb, "test")).toThrow(
|
||||||
"A template should not have more than one root node"
|
"A template should not have more than one root node"
|
||||||
@@ -652,3 +652,14 @@ describe("t-on", () => {
|
|||||||
expect(a).toBe(6);
|
expect(a).toBe(6);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe("t-ref", () => {
|
||||||
|
test("can get a ref on a node", () => {
|
||||||
|
const qweb = new QWeb();
|
||||||
|
qweb.addTemplate("test", `<div><span t-ref="myspan"/></div>`);
|
||||||
|
let refs: any = {};
|
||||||
|
renderToDOM(qweb, "test", { refs});
|
||||||
|
expect(refs.myspan.tagName).toBe('SPAN');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
+23
-10
@@ -120,21 +120,34 @@ describe("destroy method", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("composition", () => {
|
describe("composition", () => {
|
||||||
|
|
||||||
|
class WidgetB extends Widget {
|
||||||
|
template= `<div>world</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class WidgetA extends Widget {
|
||||||
|
name="a";
|
||||||
|
template= `<div>Hello<t t-widget="b"/></div>`;
|
||||||
|
widgets = {b: WidgetB}
|
||||||
|
}
|
||||||
|
|
||||||
test("a widget with a sub widget", async () => {
|
test("a widget with a sub widget", async () => {
|
||||||
|
|
||||||
class WidgetB extends Widget {
|
|
||||||
template= `<div>world</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
class WidgetA extends Widget {
|
|
||||||
name="a";
|
|
||||||
template= `<div>Hello<t t-widget="b"/></div>`;
|
|
||||||
widgets = {b: WidgetB}
|
|
||||||
}
|
|
||||||
|
|
||||||
const widget = makeWidget(WidgetA);
|
const widget = makeWidget(WidgetA);
|
||||||
const target = document.createElement("div");
|
const target = document.createElement("div");
|
||||||
await widget.mount(target);
|
await widget.mount(target);
|
||||||
expect(target.innerHTML).toBe("<div>Hello<div>world</div></div>");
|
expect(target.innerHTML).toBe("<div>Hello<div>world</div></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("t-refs on widget are widgets", async () => {
|
||||||
|
class WidgetC extends Widget {
|
||||||
|
name="a";
|
||||||
|
template= `<div t-debug="1">Hello<t t-ref="mywidgetb" t-widget="b"/></div>`;
|
||||||
|
widgets = {b: WidgetB}
|
||||||
|
}
|
||||||
|
const widget = makeWidget(WidgetC);
|
||||||
|
const target = document.createElement("div");
|
||||||
|
await widget.mount(target);
|
||||||
|
expect(widget.refs.mywidgetb instanceof WidgetB).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user