mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: properly capture expression of t-model
This commit is contained in:
committed by
Géry Debongnie
parent
c813a1ce03
commit
0e13b859d0
@@ -628,23 +628,25 @@ export class CodeGenerator {
|
||||
} = ast.model;
|
||||
|
||||
const baseExpression = compileExpr(baseExpr);
|
||||
const id = this.generateId();
|
||||
this.addLine(`const bExpr${id} = ${baseExpression};`);
|
||||
const bExprId = this.generateId("bExpr");
|
||||
this.addLine(`const ${bExprId} = ${baseExpression};`);
|
||||
|
||||
const expression = compileExpr(expr);
|
||||
const exprId = this.generateId("expr");
|
||||
this.addLine(`const ${exprId} = ${expression};`);
|
||||
|
||||
const fullExpression = `${bExprId}[${exprId}]`;
|
||||
|
||||
let idx: number;
|
||||
if (specialInitTargetAttr) {
|
||||
idx = block!.insertData(
|
||||
`${baseExpression}[${expression}] === '${attrs[targetAttr]}'`,
|
||||
"attr"
|
||||
);
|
||||
idx = block!.insertData(`${fullExpression} === '${attrs[targetAttr]}'`, "attr");
|
||||
attrs[`block-attribute-${idx}`] = specialInitTargetAttr;
|
||||
} else if (hasDynamicChildren) {
|
||||
tModelSelectedExpr = `bValue${id}`;
|
||||
this.addLine(`let ${tModelSelectedExpr} = ${baseExpression}[${expression}]`);
|
||||
const bValueId = this.generateId("bValue");
|
||||
tModelSelectedExpr = `${bValueId}`;
|
||||
this.addLine(`let ${tModelSelectedExpr} = ${fullExpression}`);
|
||||
} else {
|
||||
idx = block!.insertData(`${baseExpression}[${expression}]`, "attr");
|
||||
idx = block!.insertData(`${fullExpression}`, "attr");
|
||||
attrs[`block-attribute-${idx}`] = targetAttr;
|
||||
}
|
||||
this.helpers.add("toNumber");
|
||||
@@ -652,7 +654,7 @@ export class CodeGenerator {
|
||||
valueCode = shouldTrim ? `${valueCode}.trim()` : valueCode;
|
||||
valueCode = shouldNumberize ? `toNumber(${valueCode})` : valueCode;
|
||||
|
||||
const handler = `[(ev) => { bExpr${id}[${expression}] = ${valueCode}; }]`;
|
||||
const handler = `[(ev) => { ${fullExpression} = ${valueCode}; }]`;
|
||||
idx = block!.insertData(handler, "hdlr");
|
||||
attrs[`block-handler-${idx}`] = eventType;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,9 @@ exports[`t-model directive .lazy modifier 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -28,8 +29,9 @@ exports[`t-model directive .number modifier 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['number'];
|
||||
let hdlr1 = [(ev) => { bExpr1['number'] = toNumber(ev.target.value); }];
|
||||
const expr1 = 'number';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = toNumber(ev.target.value); }];
|
||||
let txt1 = ctx['state'].number;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -46,8 +48,9 @@ exports[`t-model directive .trim modifier 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value.trim(); }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value.trim(); }];
|
||||
let txt1 = ctx['state'].text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -64,8 +67,9 @@ exports[`t-model directive basic use, on an input 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -82,8 +86,9 @@ exports[`t-model directive basic use, on an input with bracket expression 1`] =
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -100,8 +105,9 @@ exports[`t-model directive basic use, on another key in component 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['some'];
|
||||
let attr1 = ctx['some']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['some'].text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -119,8 +125,9 @@ exports[`t-model directive can also define t-on directive on same event, part 1
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let hdlr1 = [ctx['onInput'], ctx];
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr2 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr2 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
return block1([hdlr1, attr1, hdlr2]);
|
||||
}
|
||||
}"
|
||||
@@ -137,16 +144,19 @@ exports[`t-model directive can also define t-on directive on same event, part 2
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let hdlr1 = [ctx['onClick'], ctx];
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['choice'] === 'One';
|
||||
let hdlr2 = [(ev) => { bExpr1['choice'] = ev.target.value; }];
|
||||
const expr1 = 'choice';
|
||||
let attr1 = bExpr1[expr1] === 'One';
|
||||
let hdlr2 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let hdlr3 = [ctx['onClick'], ctx];
|
||||
const bExpr2 = ctx['state'];
|
||||
let attr2 = ctx['state']['choice'] === 'Two';
|
||||
let hdlr4 = [(ev) => { bExpr2['choice'] = ev.target.value; }];
|
||||
const expr2 = 'choice';
|
||||
let attr2 = bExpr2[expr2] === 'Two';
|
||||
let hdlr4 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
|
||||
let hdlr5 = [ctx['onClick'], ctx];
|
||||
const bExpr3 = ctx['state'];
|
||||
let attr3 = ctx['state']['choice'] === 'Three';
|
||||
let hdlr6 = [(ev) => { bExpr3['choice'] = ev.target.value; }];
|
||||
const expr3 = 'choice';
|
||||
let attr3 = bExpr3[expr3] === 'Three';
|
||||
let hdlr6 = [(ev) => { bExpr3[expr3] = ev.target.value; }];
|
||||
return block1([hdlr1, attr1, hdlr2, hdlr3, attr2, hdlr4, hdlr5, attr3, hdlr6]);
|
||||
}
|
||||
}"
|
||||
@@ -165,8 +175,9 @@ exports[`t-model directive following a scope protecting directive (e.g. t-set) 1
|
||||
ctx[isBoundary] = 1
|
||||
setContextValue(ctx, \\"admiral\\", 'Bruno');
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
return block1([attr1, hdlr1]);
|
||||
}
|
||||
}"
|
||||
@@ -188,8 +199,9 @@ exports[`t-model directive in a t-foreach 1`] = `
|
||||
ctx[\`thing\`] = v_block2[i1];
|
||||
let key1 = ctx['thing'].id;
|
||||
const bExpr1 = ctx['thing'];
|
||||
let attr1 = ctx['thing']['f'];
|
||||
let hdlr1 = [(ev) => { bExpr1['f'] = ev.target.checked; }];
|
||||
const expr1 = 'f';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.checked; }];
|
||||
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
@@ -215,8 +227,37 @@ exports[`t-model directive in a t-foreach, part 2 1`] = `
|
||||
ctx[\`thing_index\`] = i1;
|
||||
let key1 = ctx['thing_index'];
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state'][ctx['thing_index']];
|
||||
let hdlr1 = [(ev) => { bExpr1[ctx['thing_index']] = ev.target.value; }];
|
||||
const expr1 = ctx['thing_index'];
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
return block1([], [b2]);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-model directive in a t-foreach, part 3 1`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||
let { prepareList, toNumber, withKey } = helpers;
|
||||
|
||||
let block1 = createBlock(\`<div><block-child-0/></div>\`);
|
||||
let block3 = createBlock(\`<input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
ctx = Object.create(ctx);
|
||||
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['names']);
|
||||
for (let i1 = 0; i1 < l_block2; i1++) {
|
||||
ctx[\`name\`] = v_block2[i1];
|
||||
ctx[\`name_index\`] = i1;
|
||||
let key1 = ctx['name_index'];
|
||||
const bExpr1 = ctx['state'].values;
|
||||
const expr1 = ctx['name'];
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
c_block2[i1] = withKey(block3([attr1, hdlr1]), key1);
|
||||
}
|
||||
let b2 = list(c_block2);
|
||||
@@ -235,8 +276,9 @@ exports[`t-model directive on a select 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['color'];
|
||||
let hdlr1 = [(ev) => { bExpr1['color'] = ev.target.value; }];
|
||||
const expr1 = 'color';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].color;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -253,8 +295,9 @@ exports[`t-model directive on a select, initial state 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['color'];
|
||||
let hdlr1 = [(ev) => { bExpr1['color'] = ev.target.value; }];
|
||||
const expr1 = 'color';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
return block1([attr1, hdlr1]);
|
||||
}
|
||||
}"
|
||||
@@ -270,8 +313,9 @@ exports[`t-model directive on a sub state key 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'].something;
|
||||
let attr1 = ctx['state'].something['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].something.text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -288,11 +332,13 @@ exports[`t-model directive on an input type=radio 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['choice'] === 'One';
|
||||
let hdlr1 = [(ev) => { bExpr1['choice'] = ev.target.value; }];
|
||||
const expr1 = 'choice';
|
||||
let attr1 = bExpr1[expr1] === 'One';
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
const bExpr2 = ctx['state'];
|
||||
let attr2 = ctx['state']['choice'] === 'Two';
|
||||
let hdlr2 = [(ev) => { bExpr2['choice'] = ev.target.value; }];
|
||||
const expr2 = 'choice';
|
||||
let attr2 = bExpr2[expr2] === 'Two';
|
||||
let hdlr2 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].choice;
|
||||
return block1([attr1, hdlr1, attr2, hdlr2, txt1]);
|
||||
}
|
||||
@@ -309,11 +355,13 @@ exports[`t-model directive on an input type=radio, with initial value 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['choice'] === 'One';
|
||||
let hdlr1 = [(ev) => { bExpr1['choice'] = ev.target.value; }];
|
||||
const expr1 = 'choice';
|
||||
let attr1 = bExpr1[expr1] === 'One';
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
const bExpr2 = ctx['state'];
|
||||
let attr2 = ctx['state']['choice'] === 'Two';
|
||||
let hdlr2 = [(ev) => { bExpr2['choice'] = ev.target.value; }];
|
||||
const expr2 = 'choice';
|
||||
let attr2 = bExpr2[expr2] === 'Two';
|
||||
let hdlr2 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
|
||||
return block1([attr1, hdlr1, attr2, hdlr2]);
|
||||
}
|
||||
}"
|
||||
@@ -330,8 +378,9 @@ exports[`t-model directive on an input, type=checkbox 1`] = `
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
let b2,b3;
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['flag'];
|
||||
let hdlr1 = [(ev) => { bExpr1['flag'] = ev.target.checked; }];
|
||||
const expr1 = 'flag';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.checked; }];
|
||||
if (ctx['state'].flag) {
|
||||
b2 = text(\`yes\`);
|
||||
} else {
|
||||
@@ -352,8 +401,9 @@ exports[`t-model directive on an textarea 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text'] = ev.target.value; }];
|
||||
const expr1 = 'text';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].text;
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
@@ -370,8 +420,9 @@ exports[`t-model directive t-model on select with static options 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['model'];
|
||||
let hdlr1 = [(ev) => { bExpr1['model'] = ev.target.value; }];
|
||||
const expr1 = 'model';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = 'a';
|
||||
let txt2 = 'b';
|
||||
let txt3 = 'c';
|
||||
@@ -390,8 +441,9 @@ exports[`t-model directive t-model with dynamic values on select options -- 2 1`
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let bValue1 = ctx['state']['model']
|
||||
let hdlr1 = [(ev) => { bExpr1['model'] = ev.target.value; }];
|
||||
const expr1 = 'model';
|
||||
let bValue1 = bExpr1[expr1]
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let attr1 = ctx['options'][0];
|
||||
let attr2 = bValue1 === ctx['options'][0];
|
||||
let txt1 = ctx['options'][0];
|
||||
@@ -413,8 +465,9 @@ exports[`t-model directive t-model with dynamic values on select options -- 3 1`
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let bValue1 = ctx['state']['model']
|
||||
let hdlr1 = [(ev) => { bExpr1['model'] = ev.target.value; }];
|
||||
const expr1 = 'model';
|
||||
let bValue1 = bExpr1[expr1]
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let attr1 = ctx['options'][0];
|
||||
let attr2 = bValue1 === ctx['options'][0];
|
||||
let txt1 = ctx['options'][0];
|
||||
@@ -435,8 +488,9 @@ exports[`t-model directive t-model with dynamic values on select options 1`] = `
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let bValue1 = ctx['state']['model']
|
||||
let hdlr1 = [(ev) => { bExpr1['model'] = ev.target.value; }];
|
||||
const expr1 = 'model';
|
||||
let bValue1 = bExpr1[expr1]
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let attr1 = ctx['options'][0];
|
||||
let attr2 = bValue1 === ctx['options'][0];
|
||||
let txt1 = ctx['options'][0];
|
||||
@@ -459,8 +513,9 @@ exports[`t-model directive t-model with dynamic values on select options in fore
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'];
|
||||
let bValue1 = ctx['state']['model']
|
||||
let hdlr1 = [(ev) => { bExpr1['model'] = ev.target.value; }];
|
||||
const expr1 = 'model';
|
||||
let bValue1 = bExpr1[expr1]
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
ctx = Object.create(ctx);
|
||||
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['options']);
|
||||
for (let i1 = 0; i1 < l_block2; i1++) {
|
||||
@@ -491,17 +546,38 @@ exports[`t-model directive two inputs in a div alternating with a t-if 1`] = `
|
||||
let b2,b3;
|
||||
if (ctx['state'].flag) {
|
||||
const bExpr1 = ctx['state'];
|
||||
let attr1 = ctx['state']['text1'];
|
||||
let hdlr1 = [(ev) => { bExpr1['text1'] = ev.target.value; }];
|
||||
const expr1 = 'text1';
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
b2 = block2([attr1, hdlr1]);
|
||||
}
|
||||
if (!ctx['state'].flag) {
|
||||
const bExpr2 = ctx['state'];
|
||||
let attr2 = ctx['state']['text2'];
|
||||
let hdlr2 = [(ev) => { bExpr2['text2'] = ev.target.value; }];
|
||||
const expr2 = 'text2';
|
||||
let attr2 = bExpr2[expr2];
|
||||
let hdlr2 = [(ev) => { bExpr2[expr2] = ev.target.value; }];
|
||||
b3 = block3([attr2, hdlr2]);
|
||||
}
|
||||
return block1([], [b2, b3]);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-model directive with expression having a changing key 1`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||
let { toNumber } = helpers;
|
||||
|
||||
let block1 = createBlock(\`<div><input block-attribute-0=\\"value\\" block-handler-1=\\"input\\"/><span><block-text-2/></span></div>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const bExpr1 = ctx['state'].something;
|
||||
const expr1 = ctx['text'].key;
|
||||
let attr1 = bExpr1[expr1];
|
||||
let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }];
|
||||
let txt1 = ctx['state'].something[ctx['text'].key];
|
||||
return block1([attr1, hdlr1, txt1]);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -246,6 +246,34 @@ describe("t-model directive", () => {
|
||||
expect(fixture.innerHTML).toBe("<div><input><span>test</span></div>");
|
||||
});
|
||||
|
||||
test("with expression having a changing key", async () => {
|
||||
class SomeComponent extends Component {
|
||||
static template = xml`
|
||||
<div>
|
||||
<input t-model="state.something[text.key]"/>
|
||||
<span><t t-esc="state.something[text.key]"/></span>
|
||||
</div>
|
||||
`;
|
||||
state: { something: { [key: string]: string } } = useState({ something: {} });
|
||||
text = useState({ key: "foo" });
|
||||
}
|
||||
const comp = await mount(SomeComponent, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><input><span></span></div>");
|
||||
|
||||
let input = fixture.querySelector("input")!;
|
||||
await editInput(input, "footest");
|
||||
expect(comp.state.something[comp.text.key]).toBe("footest");
|
||||
expect(fixture.innerHTML).toBe("<div><input><span>footest</span></div>");
|
||||
|
||||
comp.text.key = "bar";
|
||||
await nextTick();
|
||||
input = fixture.querySelector("input")!;
|
||||
await editInput(input, "test bar");
|
||||
expect(comp.state.something[comp.text.key]).toBe("test bar");
|
||||
expect(fixture.innerHTML).toBe("<div><input><span>test bar</span></div>");
|
||||
});
|
||||
|
||||
test(".lazy modifier", async () => {
|
||||
class SomeComponent extends Component {
|
||||
static template = xml`
|
||||
@@ -360,6 +388,26 @@ describe("t-model directive", () => {
|
||||
expect(comp.state).toEqual(["zuko", "uncle iroh"]);
|
||||
});
|
||||
|
||||
test("in a t-foreach, part 3", async () => {
|
||||
class SomeComponent extends Component {
|
||||
static template = xml`
|
||||
<div>
|
||||
<t t-foreach="names" t-as="name" t-key="name_index">
|
||||
<input t-model="state.values[name]"/>
|
||||
</t>
|
||||
</div>
|
||||
`;
|
||||
names = ["Crusher", "Data", "Riker", "Worf"];
|
||||
state = useState({ values: {} });
|
||||
}
|
||||
const comp = await mount(SomeComponent, fixture);
|
||||
expect(comp.state).toEqual({ values: {} });
|
||||
|
||||
const input = fixture.querySelectorAll("input")[1]!;
|
||||
await editInput(input, "Commander");
|
||||
expect(comp.state).toEqual({ values: { Data: "Commander" } });
|
||||
});
|
||||
|
||||
test("two inputs in a div alternating with a t-if", async () => {
|
||||
class SomeComponent extends Component {
|
||||
static template = xml`
|
||||
|
||||
Reference in New Issue
Block a user