diff --git a/demo/src/Counter.ts b/demo/src/Counter.ts index 94ebde9e..b52b00ee 100644 --- a/demo/src/Counter.ts +++ b/demo/src/Counter.ts @@ -15,9 +15,9 @@ export default class Counter extends Widget { counter: 0 }; - constructor(parent: Widget | null, initialState?: number) { + constructor(parent: Widget, props: {initialState?: number}) { super(parent); - this.state.counter = initialState || 0; + this.state.counter = props.initialState || 0; } increment(delta: number) { diff --git a/demo/src/RootWidget.ts b/demo/src/RootWidget.ts new file mode 100644 index 00000000..36cac83c --- /dev/null +++ b/demo/src/RootWidget.ts @@ -0,0 +1,29 @@ +import Widget from "../../src/core/widget"; +import Counter from "./Counter"; + +const template = ` +
+ Root Widget + + + + + + +
+`; + +export default class RootWidget extends Widget { + name = "root"; + template = template; + widgets = { Counter }; + state = { validcounter: true}; + + resetCounter(ev: MouseEvent) { + this.refs.counter.updateState({counter: 3}) + } + + toggle() { + this.updateState({validcounter: !this.state.validcounter}); + } +} diff --git a/demo/src/main.ts b/demo/src/main.ts index da0509d8..e9bc27b9 100644 --- a/demo/src/main.ts +++ b/demo/src/main.ts @@ -1,11 +1,10 @@ /// -// import RootWidget from "./RootWidget"; -import Counter from "./Counter"; +import RootWidget from "./RootWidget"; import env from "./env"; document.addEventListener("DOMContentLoaded", async function() { - const rootWidget = new Counter(null); + const rootWidget = new RootWidget(null); rootWidget.setEnvironment(env); const mainDiv = document.getElementById("app")!; await rootWidget.mount(mainDiv); diff --git a/src/core/qweb_directives.ts b/src/core/qweb_directives.ts index 2594e56d..e604c421 100644 --- a/src/core/qweb_directives.ts +++ b/src/core/qweb_directives.ts @@ -218,6 +218,25 @@ const onDirective: Directive = { } }; +const widgetDirective: Directive = { + name: "widget", + priority: 100, + atNodeEncounter({ ctx, fullName, value, node, qweb}): boolean { + let spanID = ctx.generateID(); + ctx.addLine(`let ${spanID} = document.createElement('span')`); + ctx.addNode(spanID) + let props = node.getAttribute('t-props'); + let widgetID = ctx.generateID(); + ctx.addLine(`let ${widgetID} = new context.widgets['${value}'](context, ${props})`); + ctx.addLine(`${widgetID}.mount(${spanID}).then(()=>${ctx.parentNode}.replaceChild(${widgetID}.el, ${spanID}))`); + let ref = node.getAttribute('t-ref'); + if (ref) { + ctx.addLine(`context.refs['${ref}'] = ${widgetID}`); + } + return true; + } +}; + export default [ forEachDirective, ifDirective, @@ -227,5 +246,6 @@ export default [ setDirective, escDirective, rawDirective, - onDirective + onDirective, + widgetDirective ]; diff --git a/src/core/widget.ts b/src/core/widget.ts index 46d03707..5f017267 100644 --- a/src/core/widget.ts +++ b/src/core/widget.ts @@ -44,6 +44,8 @@ export default class Widget { async mount(target: HTMLElement) { await this.willStart(); + this.env!.qweb.addTemplate(this.name, this.template); + delete this.template; await this.render(); target.appendChild(this.el!); } @@ -56,8 +58,6 @@ export default class Widget { setEnvironment(env: Env) { this.env = Object.create(env); - env.qweb.addTemplate(this.name, this.template); - delete this.template; } async updateState(newState: Object) {