From 20b33f50fae82849a24eaafc47532116c9323be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 23 Apr 2019 11:28:30 +0200 Subject: [PATCH] [FIX] component: bind t-ref widgets at correct moment closes #51 --- src/qweb.ts | 6 ++---- tests/__snapshots__/component.test.ts.snap | 6 +++--- tests/component.test.ts | 23 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/qweb.ts b/src/qweb.ts index 7c8b3a03..1dd49bb7 100644 --- a/src/qweb.ts +++ b/src/qweb.ts @@ -1072,9 +1072,7 @@ const widgetDirective: Directive = { ctx.addLine(`w${widgetID}.on('${event}', owner, owner['${method}'])`); } let ref = node.getAttribute("t-ref"); - if (ref) { - ctx.addLine(`context.refs[${ctx.formatExpression(ref)}] = w${widgetID};`); - } + let refExpr = ref ? `context.refs[${ctx.formatExpression(ref)}] = w${widgetID};` : ''; ctx.addLine(`def${defID} = w${widgetID}._prepare();`); ctx.closeIf(); @@ -1084,7 +1082,7 @@ const widgetDirective: Directive = { ctx.addLine( `def${defID} = def${defID}.then(vnode=>{let pvnode=h(vnode.sel, {key: ${templateID}});c${ ctx.parentNode - }[_${dummyID}_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w${widgetID}._mount(vnode, vn.elm);pvnode.elm=nvn.elm},remove(){w${widgetID}.${ + }[_${dummyID}_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w${widgetID}._mount(vnode, vn.elm);pvnode.elm=nvn.elm;${refExpr}},remove(){w${widgetID}.${ keepAlive ? "unmount" : "destroy" }()},destroy(){w${widgetID}.${ keepAlive ? "unmount" : "destroy" diff --git a/tests/__snapshots__/component.test.ts.snap b/tests/__snapshots__/component.test.ts.snap index f27aac4d..b87f8a3e 100644 --- a/tests/__snapshots__/component.test.ts.snap +++ b/tests/__snapshots__/component.test.ts.snap @@ -51,7 +51,7 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = ` } } if (isNew7) { - def6 = def6.then(vnode=>{let pvnode=h(vnode.sel, {key: key8});c1[_5_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w7._mount(vnode, vn.elm);pvnode.elm=nvn.elm},remove(){w7.destroy()},destroy(){w7.destroy()}}; w7.__owl__.pvnode = pvnode;}); + def6 = def6.then(vnode=>{let pvnode=h(vnode.sel, {key: key8});c1[_5_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w7._mount(vnode, vn.elm);pvnode.elm=nvn.elm;},remove(){w7.destroy()},destroy(){w7.destroy()}}; w7.__owl__.pvnode = pvnode;}); } else { def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let vnode;if (!w7.__owl__.vnode){vnode=w7.__owl__.pvnode} else { vnode=h(w7.__owl__.vnode.sel, {key: key8});vnode.elm=w7.el;vnode.data.hook = {insert(a){a.elm.parentNode.replaceChild(w7.el,a.elm);a.elm=w7.el;w7.__mount();},remove(){w7.destroy()}, destroy() {w7.destroy()}}}c1[_5_index]=vnode;}); } @@ -99,7 +99,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = ` } } if (isNew4) { - def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: key5});c1[_2_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w4._mount(vnode, vn.elm);pvnode.elm=nvn.elm},remove(){w4.destroy()},destroy(){w4.destroy()}}; w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: key5});c1[_2_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w4._mount(vnode, vn.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}; w4.__owl__.pvnode = pvnode;}); } else { def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let vnode;if (!w4.__owl__.vnode){vnode=w4.__owl__.pvnode} else { vnode=h(w4.__owl__.vnode.sel, {key: key5});vnode.elm=w4.el;vnode.data.hook = {insert(a){a.elm.parentNode.replaceChild(w4.el,a.elm);a.elm=w4.el;w4.__mount();},remove(){w4.destroy()}, destroy() {w4.destroy()}}}c1[_2_index]=vnode;}); } @@ -145,7 +145,7 @@ exports[`random stuff/miscellaneous t-props should not be undefined (snapshottin } } if (isNew4) { - def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4});c1[_2_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w4._mount(vnode, vn.elm);pvnode.elm=nvn.elm},remove(){w4.destroy()},destroy(){w4.destroy()}}; w4.__owl__.pvnode = pvnode;}); + def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4});c1[_2_index]=pvnode;pvnode.data.hook = {insert(vn){let nvn=w4._mount(vnode, vn.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}; w4.__owl__.pvnode = pvnode;}); } else { def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let vnode;if (!w4.__owl__.vnode){vnode=w4.__owl__.pvnode} else { vnode=h(w4.__owl__.vnode.sel, {key: 4});vnode.elm=w4.el;vnode.data.hook = {insert(a){a.elm.parentNode.replaceChild(w4.el,a.elm);a.elm=w4.el;w4.__mount();},remove(){w4.destroy()}, destroy() {w4.destroy()}}}c1[_2_index]=vnode;}); } diff --git a/tests/component.test.ts b/tests/component.test.ts index 17af6946..eb4a0f33 100644 --- a/tests/component.test.ts +++ b/tests/component.test.ts @@ -657,6 +657,29 @@ describe("composition", () => { expect(widget.refs.mywidgetb instanceof WidgetB).toBe(true); }); + test("t-refs are bound at proper timing", async () => { + expect.assertions(2); + class ParentWidget extends Widget { + inlineTemplate = ` +
+ +
`; + widgets = { Widget }; + state = {list: []}; + willPatch() { + expect(this.refs.child).toBeUndefined(); + } + patched() { + expect(this.refs.child).not.toBeUndefined(); + } + } + + const parent = new ParentWidget(env); + await parent.mount(fixture); + parent.state.list.push(1); + await nextTick() + }); + test("modifying a sub widget", async () => { class ParentWidget extends Widget { inlineTemplate = `
`;