mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] qweb: t-foreach needs to hold on scope
Have a t-on within a t-foreach the t-on has an expression Before this commit, when triggering the t-on, the expression was falsely evaluated In details, the expression took scope from outside the foreach loop as we protect it to have similar results than an actual for loop But, at triggering time, the scope protection had already been terminated meaning the info of the iteration of the loop the handler has been built in had already disappeared This commit fixes that closes #594
This commit is contained in:
committed by
Géry Debongnie
parent
21737d33fa
commit
21d1306ec2
@@ -2902,6 +2902,115 @@ describe("other directives with t-component", () => {
|
||||
await widget.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe("<div><p>InLoop: 0</p><p>InLoop: 1</p><p>EndLoop: 1</p></div>");
|
||||
});
|
||||
|
||||
test("t-on expression in t-foreach", async () => {
|
||||
class SomeWidget extends Component<any, any> {
|
||||
static template = xml`
|
||||
<div>
|
||||
<div t-foreach="state.values" t-as="val" t-key="val">
|
||||
<t t-esc="val_index"/>: <t t-esc="val + ''"/>
|
||||
<button t-on-click="otherState.vals.push(val)">Expr</button>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
state = useState({values: ['a', 'b']});
|
||||
otherState = {vals: []};
|
||||
}
|
||||
const widget = new SomeWidget();
|
||||
await widget.mount(fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><div>0: a<button>Expr</button></div><div>1: b<button>Expr</button></div></div>");
|
||||
expect(widget.otherState.vals).toStrictEqual([]);
|
||||
const buttons = fixture.querySelectorAll('button');
|
||||
buttons[0].click();
|
||||
buttons[1].click();
|
||||
expect(widget.otherState.vals).toStrictEqual(['a', 'b']);
|
||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on expression in t-foreach with t-set", async () => {
|
||||
class SomeWidget extends Component<any, any> {
|
||||
static template = xml`
|
||||
<div>
|
||||
<t t-set="bossa" t-value="'nova'"/>
|
||||
<div t-foreach="state.values" t-as="val" t-key="val">
|
||||
<t t-set="bossa" t-value="bossa + '_' + val_index" />
|
||||
<t t-esc="val_index"/>: <t t-esc="val + ''"/>
|
||||
<button t-on-click="otherState.vals.push(val + '_' + bossa)">Expr</button>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
state = useState({values: ['a', 'b']});
|
||||
otherState = {vals: []};
|
||||
}
|
||||
const widget = new SomeWidget();
|
||||
await widget.mount(fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><div>0: a<button>Expr</button></div><div>1: b<button>Expr</button></div></div>");
|
||||
expect(widget.otherState.vals).toStrictEqual([]);
|
||||
const buttons = fixture.querySelectorAll('button');
|
||||
buttons[0].click();
|
||||
buttons[1].click();
|
||||
expect(widget.otherState.vals).toStrictEqual(['a_nova_0', 'b_nova_0_1']);
|
||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on method call in t-foreach", async () => {
|
||||
class SomeWidget extends Component<any, any> {
|
||||
static template = xml`
|
||||
<div>
|
||||
<div t-foreach="state.values" t-as="val" t-key="val">
|
||||
<t t-esc="val_index"/>: <t t-esc="val + ''"/>
|
||||
<button t-on-click="addVal(val)">meth call</button>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
state = useState({values: ['a', 'b']});
|
||||
otherState = {vals: new Array<string>()};
|
||||
|
||||
addVal(val: string) {
|
||||
this.otherState.vals.push(val);
|
||||
}
|
||||
}
|
||||
const widget = new SomeWidget();
|
||||
await widget.mount(fixture);
|
||||
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><div>0: a<button>meth call</button></div><div>1: b<button>meth call</button></div></div>");
|
||||
expect(widget.otherState.vals).toStrictEqual([]);
|
||||
const buttons = fixture.querySelectorAll('button');
|
||||
buttons[0].click();
|
||||
buttons[1].click();
|
||||
expect(widget.otherState.vals).toStrictEqual(['a', 'b']);
|
||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on expression captured in t-foreach", async () => {
|
||||
class SomeWidget extends Component<any, any> {
|
||||
static template = xml`
|
||||
<div>
|
||||
<t t-set="iter" t-value="0" />
|
||||
<div t-foreach="arr" t-as="val" t-key="val">
|
||||
<button t-on-click="otherState.vals.push(iter + '_' + iter)">expr</button>
|
||||
<t t-set="iter" t-value="iter + 1" />
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
arr = ['a', 'b']
|
||||
otherState = {vals: new Array<string>()};
|
||||
}
|
||||
const widget = new SomeWidget();
|
||||
await widget.mount(fixture);
|
||||
|
||||
|
||||
expect(fixture.innerHTML).toBe("<div><div><button>expr</button></div><div><button>expr</button></div></div>");
|
||||
expect(widget.otherState.vals).toStrictEqual([]);
|
||||
const buttons = fixture.querySelectorAll('button');
|
||||
buttons[0].click();
|
||||
buttons[1].click();
|
||||
expect(widget.otherState.vals).toStrictEqual(['0_0', '1_1']);
|
||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("random stuff/miscellaneous", () => {
|
||||
|
||||
Reference in New Issue
Block a user