[FIX] qweb: t-call properly transfer key to sub components

Since t-call is now a function call, we need to properly handle the
internal key used to find previous components.  If a t-call is inside a
t-foreach, then we need to transfer the key to the sub template.
Otherwise, each component in the subtemplate will be associated to the
same key, which means that it will lead to big issues: components are
destroyed and reused...

closes #581
This commit is contained in:
Géry Debongnie
2019-12-16 14:20:36 +01:00
committed by aab-odoo
parent d9bf4284c6
commit 9216c5c24b
5 changed files with 230 additions and 180 deletions
+8 -8
View File
@@ -1,6 +1,7 @@
import { CompilationContext } from "./compilation_context";
import { QWeb } from "./qweb";
import { htmlToVDOM } from "../vdom/html_to_vdom";
import { QWebVar } from "./expression_parser";
/**
* Owl QWeb Directives
@@ -119,7 +120,7 @@ QWeb.addDirective({
ctx.rootContext.shouldDefineScope = true;
const variable = node.getAttribute("t-set")!;
let value = node.getAttribute("t-value")!;
ctx.variables[variable] = ctx.variables[variable] || {};
ctx.variables[variable] = ctx.variables[variable] || ({} as QWebVar);
let qwebvar = ctx.variables[variable];
const hasBody = node.hasChildNodes();
@@ -229,7 +230,7 @@ QWeb.addDirective({
// ------------------------------------------------
if (!qweb.subTemplates[subTemplate]) {
qweb.subTemplates[subTemplate] = true;
const subTemplateFn = qweb._compile(subTemplate, nodeTemplate.elem, ctx);
const subTemplateFn = qweb._compile(subTemplate, nodeTemplate.elem, ctx, true);
qweb.subTemplates[subTemplate] = subTemplateFn;
}
@@ -264,17 +265,16 @@ QWeb.addDirective({
// ------------------------------------------------
const callingScope = hasBody ? "scope" : "Object.assign(Object.create(context), scope)";
const parentComponent = `utils.getComponent(context)`;
const keyCode = ctx.loopNumber ? `, key: ${ctx.generateTemplateKey()}` : "";
const parentNode = ctx.parentNode ? `c${ctx.parentNode}` : "result";
const extra = `Object.assign({}, extra, {parentNode: ${parentNode}, parent: ${parentComponent}${keyCode}})`;
if (ctx.parentNode) {
ctx.addLine(
`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, Object.assign({}, extra, {parentNode: c${ctx.parentNode}, parent: ${parentComponent}}));`
);
ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
} else {
// this is a t-call with no parentnode, we need to extract the result
ctx.rootContext.shouldDefineResult = true;
ctx.addLine(`result = []`);
ctx.addLine(
`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, Object.assign({}, extra, {parentNode: result, parent: ${parentComponent}}));`
);
ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
ctx.addLine(`result = result[0]`);
}
+10 -1
View File
@@ -383,7 +383,12 @@ export class QWeb extends EventBus {
});
}
_compile(name: string, elem: Element, parentContext?: CompilationContext): CompiledTemplate {
_compile(
name: string,
elem: Element,
parentContext?: CompilationContext,
defineKey?: boolean
): CompiledTemplate {
const isDebug = elem.attributes.hasOwnProperty("t-debug");
const ctx = new CompilationContext(name);
if (elem.tagName !== "t") {
@@ -396,6 +401,10 @@ export class QWeb extends EventBus {
ctx.hasParentWidget = true;
ctx.shouldDefineResult = false;
ctx.addLine(`let c${ctx.parentNode} = extra.parentNode;`);
if (defineKey) {
ctx.currentKey = `key${ctx.generateID()}`;
ctx.addLine(`let ${ctx.currentKey} = extra.key || '';`);
}
}
this._compileNode(elem, ctx);