diff --git a/web/static/src/ts/core/qweb_vdom.ts b/web/static/src/ts/core/qweb_vdom.ts index 48f1face..13035567 100644 --- a/web/static/src/ts/core/qweb_vdom.ts +++ b/web/static/src/ts/core/qweb_vdom.ts @@ -689,7 +689,7 @@ const refDirective: Directive = { const widgetDirective: Directive = { name: "widget", priority: 100, - atNodeEncounter({ ctx, value, node }): boolean { + atNodeEncounter({ ctx, value, node, qweb }): boolean { ctx.rootContext.shouldDefineOwner = true; let dummyID = ctx.generateID(); let defID = ctx.generateID(); @@ -697,6 +697,22 @@ const widgetDirective: Directive = { ctx.addLine(`let _${dummyID}_index = c${ctx.parentNode}.length;`); ctx.addLine(`c${ctx.parentNode}.push(_${dummyID});`); let props = node.getAttribute("t-props"); + if (props) { + props = props.trim(); + if (props[0] === "{" && props[props.length - 1] === "}") { + const innerProp = props + .slice(1, -1) + .split(",") + .map(p => { + let [key, val] = p.split(":"); + return `${key}: ${qweb._formatExpression(val)}`; + }) + .join(","); + props = "{" + innerProp + "}"; + } else { + props = qweb._formatExpression(props); + } + } let widgetID = ctx.generateID(); ctx.addLine( `let _${widgetID} = new context.widgets['${value}'](owner, ${props});` diff --git a/web/static/tests/core/widget.test.ts b/web/static/tests/core/widget.test.ts index 46596340..a2031a88 100644 --- a/web/static/tests/core/widget.test.ts +++ b/web/static/tests/core/widget.test.ts @@ -517,3 +517,49 @@ describe("composition", () => { expect(children(widget)[0].env).toBe(env); }); }); + +describe("props evaluation (with t-props directive)", () => { + test("explicit object prop", async () => { + class Parent extends Widget { + name = "a"; + template = `
`; + widgets = { child: Child }; + state = { val: 42 }; + } + + class Child extends Widget { + template = ``; + state: { someval: number }; + constructor(parent: Parent, props: { value: number }) { + super(parent); + this.state = { someval: props.value }; + } + } + + const widget = new Parent(env); + await widget.mount(fixture); + expect(fixture.innerHTML).toBe("
42
"); + }); + + test("object prop value", async () => { + class Parent extends Widget { + name = "a"; + template = `
`; + widgets = { child: Child }; + state = { val: 42 }; + } + + class Child extends Widget { + template = ``; + state: { someval: number }; + constructor(parent: Parent, props: { val: number }) { + super(parent); + this.state = { someval: props.val }; + } + } + + const widget = new Parent(env); + await widget.mount(fixture); + expect(fixture.innerHTML).toBe("
42
"); + }); +});