diff --git a/src/compiler/code_generator.ts b/src/compiler/code_generator.ts
index 97ee8409..3b9a0e72 100644
--- a/src/compiler/code_generator.ts
+++ b/src/compiler/code_generator.ts
@@ -672,8 +672,9 @@ export class CodeGenerator {
this.target.hasRef = true;
const isDynamic = INTERP_REGEXP.test(ast.ref);
if (isDynamic) {
+ this.helpers.add("singleRefSetter");
const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
- const idx = block!.insertData(`(el) => refs[${str}] = el`, "ref");
+ const idx = block!.insertData(`singleRefSetter(refs, ${str})`, "ref");
attrs["block-ref"] = String(idx);
} else {
let name = ast.ref;
@@ -686,7 +687,8 @@ export class CodeGenerator {
info[1] = `multiRefSetter(refs, \`${name}\`)`;
} else {
let id = generateId("ref");
- this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
+ this.helpers.add("singleRefSetter");
+ this.target.refInfo[name] = [id, `singleRefSetter(refs, \`${name}\`)`];
const index = block!.data.push(id) - 1;
attrs["block-ref"] = String(index);
}
diff --git a/src/runtime/template_helpers.ts b/src/runtime/template_helpers.ts
index 82a68e1a..0085d7de 100644
--- a/src/runtime/template_helpers.ts
+++ b/src/runtime/template_helpers.ts
@@ -202,6 +202,16 @@ function multiRefSetter(refs: RefMap, name: string): RefSetter {
};
}
+function singleRefSetter(refs: RefMap, name: string): RefSetter {
+ let _el: HTMLElement | null = null;
+ return (el) => {
+ if (el || refs[name] === _el) {
+ refs[name] = el;
+ _el = el;
+ }
+ };
+}
+
/**
* Validate the component props (or next props) against the (static) props
* description. This is potentially an expensive operation: it may needs to
@@ -260,6 +270,7 @@ export const helpers = {
prepareList,
setContextValue,
multiRefSetter,
+ singleRefSetter,
shallowEqual,
toNumber,
validateProps,
diff --git a/tests/compiler/__snapshots__/misc.test.ts.snap b/tests/compiler/__snapshots__/misc.test.ts.snap
index 33f7acc2..b7a7ee29 100644
--- a/tests/compiler/__snapshots__/misc.test.ts.snap
+++ b/tests/compiler/__snapshots__/misc.test.ts.snap
@@ -182,7 +182,7 @@ exports[`misc other complex template 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
- let { prepareList, withKey } = helpers;
+ let { prepareList, withKey, singleRefSetter } = helpers;
const callTemplate_1 = app.getTemplate(\`LOAD_INFOS_TEMPLATE\`);
const comp1 = app.createComponent(\`BundlesList\`, true, false, false, false);
const comp2 = app.createComponent(\`BundlesList\`, true, false, false, false);
@@ -218,8 +218,8 @@ exports[`misc other complex template 1`] = `
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`search_input\`] = el;
- const ref2 = (el) => refs[\`settings_menu\`] = el;
+ const ref1 = singleRefSetter(refs, \`search_input\`);
+ const ref2 = singleRefSetter(refs, \`settings_menu\`);
let b2,b4,b14,b17,b22,b23,b24,b25;
let attr1 = \`/runbot/\${ctx['project'].slug}\`;
let txt1 = ctx['project'].name;
diff --git a/tests/compiler/__snapshots__/t_ref.test.ts.snap b/tests/compiler/__snapshots__/t_ref.test.ts.snap
index 6048615a..22ece76f 100644
--- a/tests/compiler/__snapshots__/t_ref.test.ts.snap
+++ b/tests/compiler/__snapshots__/t_ref.test.ts.snap
@@ -4,13 +4,14 @@ exports[`t-ref can get a dynamic ref on a node 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const v1 = ctx['id'];
- let ref1 = (el) => refs[\`myspan\${v1}\`] = el;
+ let ref1 = singleRefSetter(refs, \`myspan\${v1}\`);
return block1([ref1]);
}
}"
@@ -20,13 +21,14 @@ exports[`t-ref can get a dynamic ref on a node, alternate syntax 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const v1 = ctx['id'];
- let ref1 = (el) => refs[\`myspan\${v1}\`] = el;
+ let ref1 = singleRefSetter(refs, \`myspan\${v1}\`);
return block1([ref1]);
}
}"
@@ -36,12 +38,13 @@ exports[`t-ref can get a ref on a node 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`myspan\`] = el;
+ const ref1 = singleRefSetter(refs, \`myspan\`);
return block1([ref1]);
}
}"
@@ -66,12 +69,13 @@ exports[`t-ref ref in a t-call 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`12
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`name\`] = el;
+ const ref1 = singleRefSetter(refs, \`name\`);
return block1([ref1]);
}
}"
@@ -81,13 +85,14 @@ exports[`t-ref ref in a t-if 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
let block2 = createBlock(\`\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`name\`] = el;
+ const ref1 = singleRefSetter(refs, \`name\`);
let b2;
if (ctx['condition']) {
b2 = block2([ref1]);
@@ -101,7 +106,7 @@ exports[`t-ref refs in a loop 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
- let { prepareList, withKey } = helpers;
+ let { prepareList, singleRefSetter, withKey } = helpers;
let block1 = createBlock(\`
\`);
let block3 = createBlock(\`
\`);
@@ -115,7 +120,7 @@ exports[`t-ref refs in a loop 1`] = `
const key1 = ctx['item'];
const tKey_1 = ctx['item'];
const v1 = ctx['item'];
- let ref1 = (el) => refs[(v1)] = el;
+ let ref1 = singleRefSetter(refs, (v1));
let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([ref1, txt1]), tKey_1 + key1);
}
@@ -129,14 +134,15 @@ exports[`t-ref two refs, one in a t-if 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`\`);
let block2 = createBlock(\`\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`name\`] = el;
- const ref2 = (el) => refs[\`p\`] = el;
+ const ref1 = singleRefSetter(refs, \`name\`);
+ const ref2 = singleRefSetter(refs, \`p\`);
let b2;
if (ctx['condition']) {
b2 = block2([ref1]);
diff --git a/tests/components/__snapshots__/hooks.test.ts.snap b/tests/components/__snapshots__/hooks.test.ts.snap
index 3fd4d391..e7c427f7 100644
--- a/tests/components/__snapshots__/hooks.test.ts.snap
+++ b/tests/components/__snapshots__/hooks.test.ts.snap
@@ -4,14 +4,15 @@ exports[`hooks autofocus hook input in a t-if 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
let block2 = createBlock(\`\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`input1\`] = el;
- const ref2 = (el) => refs[\`input2\`] = el;
+ const ref1 = singleRefSetter(refs, \`input1\`);
+ const ref2 = singleRefSetter(refs, \`input2\`);
let b2;
if (ctx['state'].flag) {
b2 = block2([ref2]);
@@ -25,13 +26,14 @@ exports[`hooks autofocus hook simple input 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`input1\`] = el;
- const ref2 = (el) => refs[\`input2\`] = el;
+ const ref1 = singleRefSetter(refs, \`input1\`);
+ const ref2 = singleRefSetter(refs, \`input2\`);
return block1([ref1, ref2]);
}
}"
@@ -264,12 +266,13 @@ exports[`hooks useEffect hook effect can depend on stuff in dom 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block2 = createBlock(\`\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`div\`] = el;
+ const ref1 = singleRefSetter(refs, \`div\`);
let b2;
if (ctx['state'].value) {
b2 = block2([ref1]);
@@ -353,12 +356,13 @@ exports[`hooks useRef hook: basic use 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`button\`] = el;
+ const ref1 = singleRefSetter(refs, \`button\`);
let txt1 = ctx['value'];
return block1([ref1, txt1]);
}
diff --git a/tests/components/__snapshots__/refs.test.ts.snap b/tests/components/__snapshots__/refs.test.ts.snap
index e90390d4..88b0284b 100644
--- a/tests/components/__snapshots__/refs.test.ts.snap
+++ b/tests/components/__snapshots__/refs.test.ts.snap
@@ -4,12 +4,13 @@ exports[`refs basic use 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
let block1 = createBlock(\`
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`div\`] = el;
+ const ref1 = singleRefSetter(refs, \`div\`);
return block1([ref1]);
}
}"
@@ -19,7 +20,7 @@ exports[`refs can use 2 refs with same name in a t-if/t-else situation 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
- let { multiRefSetter } = helpers;
+ let { singleRefSetter, multiRefSetter } = helpers;
let block2 = createBlock(\`
\`);
let block3 = createBlock(\`
\`);
@@ -42,13 +43,14 @@ exports[`refs refs and recursive templates 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
const comp1 = app.createComponent(\`Test\`, true, false, false, false);
let block1 = createBlock(\`
\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
- const ref1 = (el) => refs[\`root\`] = el;
+ const ref1 = singleRefSetter(refs, \`root\`);
let b2;
let txt1 = ctx['props'].tree.value;
if (ctx['props'].tree.child) {
@@ -59,11 +61,33 @@ exports[`refs refs and recursive templates 1`] = `
}"
`;
+exports[`refs refs and t-key 1`] = `
+"function anonymous(app, bdom, helpers
+) {
+ let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ let { singleRefSetter } = helpers;
+
+ let block2 = createBlock(\`