[FIX] component: issue with t-slot,t-set,t-value, but no t-foreach

closes #232
This commit is contained in:
Géry Debongnie
2019-07-08 16:41:29 +02:00
parent 8e1aa71436
commit 9f1e64d399
3 changed files with 90 additions and 12 deletions
+7 -2
View File
@@ -590,8 +590,13 @@ QWeb.addDirective({
}
}
const scopeVars =
hasSlots && ctx.scopeVars.length ? `Object.assign({}, scope), {${varDefs.join(",")}}` : "";
let scopeVars = "";
if (hasSlots) {
scopeVars += ctx.scopeVars.length ? `Object.assign({}, scope)` : varDefs.length ? `{}` : "";
if (varDefs.length) {
scopeVars += `, {${varDefs.join(",")}}`;
}
}
ctx.addLine(`def${defID} = w${componentID}.__prepare(${scopeVars});`);
// hack: specify empty remove hook to prevent the node from being removed from the DOM
ctx.addLine(
+44 -2
View File
@@ -1278,10 +1278,10 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = `
w9 = new W9(owner, props9);
context.__owl__.cmap[String(-9 - i)] = w9.__owl__.id;
w9.__owl__.slotId = 1;
def8 = w9.__prepare(Object.assign({}, scope), {});
def8 = w9.__prepare(Object.assign({}, scope));
def8 = def8.then(vnode=>{let pvnode=h(vnode.sel, {key: String(-9 - i), hook: {insert(vn) {let nvn=w9.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w9.destroy();}}});c6[_7_index]=pvnode;w9.__owl__.pvnode = pvnode;});
} else {
def8 = def8 || w9.__updateProps(props9, extra.forceUpdate, extra.patchQueue, Object.assign({}, scope), {});
def8 = def8 || w9.__updateProps(props9, extra.forceUpdate, extra.patchQueue, Object.assign({}, scope));
def8 = def8.then(()=>{if (w9.__owl__.isDestroyed) {return};let pvnode=w9.__owl__.pvnode;c6[_7_index]=pvnode;});
}
extra.promises.push(def8);
@@ -1374,3 +1374,45 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
return vn1;
}"
`;
exports[`t-slot directive slots are rendered with proper context, part 4 1`] = `
"function anonymous(context,extra
) {
let utils = this.utils;
let QWeb = this.constructor;
let owner = context;
var h = this.utils.h;
let c1 = [], p1 = {key:1};
var vn1 = h('div', p1, c1);
var _2 = 'User '+context['state'].user.name;
//COMPONENT
let def4;
let w5 = 5 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[5]] : false;
let _3_index = c1.length;
c1.push(null);
let props5 = {to:'/user/'+context['state'].user.id};
if (w5 && w5.__owl__.renderPromise && !w5.__owl__.vnode) {
if (utils.shallowEqual(props5, w5.__owl__.renderProps)) {
def4 = w5.__owl__.renderPromise;
} else {
w5.destroy();
w5 = false;
}
}
if (!w5) {
let componentKey5 = \`Link\`;
let W5 = context.components && context.components[componentKey5] || QWeb.components[componentKey5];
if (!W5) {throw new Error('Cannot find the definition of component \\"' + componentKey5 + '\\"')}
w5 = new W5(owner, props5);
context.__owl__.cmap[5] = w5.__owl__.id;
w5.__owl__.slotId = 1;
def4 = w5.__prepare({}, {_2});
def4 = def4.then(vnode=>{let pvnode=h(vnode.sel, {key: 5, hook: {insert(vn) {let nvn=w5.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w5.destroy();}}});c1[_3_index]=pvnode;w5.__owl__.pvnode = pvnode;});
} else {
def4 = def4 || w5.__updateProps(props5, extra.forceUpdate, extra.patchQueue, {}, {_2});
def4 = def4.then(()=>{if (w5.__owl__.isDestroyed) {return};let pvnode=w5.__owl__.pvnode;c1[_3_index]=pvnode;});
}
extra.promises.push(def4);
return vn1;
}"
`;
+39 -8
View File
@@ -2936,15 +2936,15 @@ describe("t-slot directive", () => {
class Link extends Widget {}
class App extends Widget {
state = {users: [{id: 1, name: 'Aaron'}, {id: 2, name: 'David'}]};
components = { Link };
state = { users: [{ id: 1, name: "Aaron" }, { id: 2, name: "David" }] };
components = { Link };
}
const app = new App(env);
await app.mount(fixture);
expect(fixture.innerHTML).toBe(
"<div><u><li><a href=\"/user/1\">User Aaron</a></li><li><a href=\"/user/2\">User David</a></li></u></div>"
'<div><u><li><a href="/user/1">User Aaron</a></li><li><a href="/user/2">User David</a></li></u></div>'
);
expect(env.qweb.templates.Link.fn.toString()).toMatchSnapshot();
expect(env.qweb.templates.App.fn.toString()).toMatchSnapshot();
@@ -2953,7 +2953,7 @@ describe("t-slot directive", () => {
app.state.users[1].name = "Mathieu";
await nextTick();
expect(fixture.innerHTML).toBe(
"<div><u><li><a href=\"/user/1\">User Aaron</a></li><li><a href=\"/user/2\">User Mathieu</a></li></u></div>"
'<div><u><li><a href="/user/1">User Aaron</a></li><li><a href="/user/2">User Mathieu</a></li></u></div>'
);
});
@@ -2974,15 +2974,15 @@ describe("t-slot directive", () => {
class Link extends Widget {}
class App extends Widget {
state = {users: [{id: 1, name: 'Aaron'}, {id: 2, name: 'David'}]};
components = { Link };
state = { users: [{ id: 1, name: "Aaron" }, { id: 2, name: "David" }] };
components = { Link };
}
const app = new App(env);
await app.mount(fixture);
expect(fixture.innerHTML).toBe(
"<div><u><li><a href=\"/user/1\">User Aaron</a></li><li><a href=\"/user/2\">User David</a></li></u></div>"
'<div><u><li><a href="/user/1">User Aaron</a></li><li><a href="/user/2">User David</a></li></u></div>'
);
expect(env.qweb.templates.Link.fn.toString()).toMatchSnapshot();
expect(env.qweb.templates.App.fn.toString()).toMatchSnapshot();
@@ -2991,9 +2991,40 @@ describe("t-slot directive", () => {
app.state.users[1].name = "Mathieu";
await nextTick();
expect(fixture.innerHTML).toBe(
"<div><u><li><a href=\"/user/1\">User Aaron</a></li><li><a href=\"/user/2\">User Mathieu</a></li></u></div>"
'<div><u><li><a href="/user/1">User Aaron</a></li><li><a href="/user/2">User Mathieu</a></li></u></div>'
);
});
test("slots are rendered with proper context, part 4", async () => {
env.qweb.addTemplates(`
<templates>
<a t-name="Link" t-att-href="props.to">
<t t-slot="default"/>
</a>
<div t-name="App">
<t t-set="userdescr" t-value="'User ' + state.user.name"/>
<Link to="'/user/' + state.user.id"><t t-esc="userdescr"/></Link>
</div>
</templates>
`);
class Link extends Widget {}
class App extends Widget {
state = { user: { id: 1, name: "Aaron" } };
components = { Link };
}
const app = new App(env);
await app.mount(fixture);
expect(fixture.innerHTML).toBe('<div><a href="/user/1">User Aaron</a></div>');
expect(env.qweb.templates.App.fn.toString()).toMatchSnapshot();
// test updateprops here
app.state.user.name = "David";
await nextTick();
expect(fixture.innerHTML).toBe('<div><a href="/user/1">User David</a></div>');
});
test("refs are properly bound in slots", async () => {