diff --git a/src/component/component.ts b/src/component/component.ts index 337ead58..a53298a1 100644 --- a/src/component/component.ts +++ b/src/component/component.ts @@ -49,8 +49,13 @@ export interface Meta { cmap: { [key: number]: number }; renderId: number; + + // the renderProps and renderPromise keys are only useful for the "prepare" + // step of the lifecycle of a component. Once a component has been rendered + // and patched, it is no longer useful. renderProps: Props | null; renderPromise: Promise | null; + boundHandlers: { [key: number]: any }; observer?: Observer; render?: CompiledTemplate; @@ -447,7 +452,6 @@ export class Component { __patch(vnode) { const __owl__ = this.__owl__; - __owl__.renderPromise = null; const target = __owl__.vnode || document.createElement(vnode.sel!); if (this.__owl__.classObj) { (vnode).data.class = Object.assign((vnode).data.class || {}, this.__owl__.classObj); @@ -544,9 +548,7 @@ export class Component { // parent component. With this, we make sure that the parent component will be // able to patch itself properly after vnode.key = __owl__.id; - __owl__.renderProps = this.props; - __owl__.renderPromise = Promise.all(promises).then(() => vnode); - return __owl__.renderPromise; + return Promise.all(promises).then(() => vnode); } /** diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index ff9e0f4d..1b1890e4 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -2608,6 +2608,39 @@ describe("async rendering", () => { expect(fixture.querySelector(".children")!.innerHTML).toBe("1/11/1"); }); + + test("rendering component again in next microtick", async () => { + class Child extends Widget {} + + class App extends Widget { + components = { Child }; + + async onClick() { + (env as any).flag = true; + this.render(); + await Promise.resolve(); + this.render(); + } + } + + env.qweb.addTemplates(` + +
Child
+ +
+ + +
+
+ `); + + const app = new App(env); + await app.mount(fixture); + expect(fixture.innerHTML).toBe("
"); + fixture.querySelector("button")!.click(); + await nextTick(); + expect(fixture.innerHTML).toBe("
Child
"); + }); }); describe("updating environment", () => { @@ -3839,7 +3872,6 @@ describe("top level sub widgets", () => { expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot(); }); - test("sub widget is interactive", async () => { env.qweb.addTemplates(` @@ -3849,10 +3881,10 @@ describe("top level sub widgets", () => { child `); class Child extends Widget { - state = {val: 1}; - inc() { - this.state.val++; - } + state = { val: 1 }; + inc() { + this.state.val++; + } } class Parent extends Widget { components = { Child }; @@ -3860,7 +3892,7 @@ describe("top level sub widgets", () => { const parent = new Parent(env); await parent.mount(fixture); expect(fixture.innerHTML).toBe("child1"); - const button = fixture.querySelector('button')!; + const button = fixture.querySelector("button")!; button.click(); await nextTick(); expect(fixture.innerHTML).toBe("child2"); @@ -3907,7 +3939,7 @@ describe("top level sub widgets", () => { class Child extends Widget {} class OtherChild extends Widget {} class Parent extends Widget { - state = {flag: true} + state = { flag: true }; components = { Child, OtherChild }; } let parent = new Parent(env); @@ -3916,7 +3948,5 @@ describe("top level sub widgets", () => { parent.state.flag = false; await nextTick(); expect(fixture.innerHTML).toBe("
CHILD 2
"); - }); - });