[REF] component: improve render method

This commit is contained in:
Géry Debongnie
2019-08-23 22:22:34 +02:00
parent 34e463ad0a
commit 9843d16585
4 changed files with 24 additions and 11 deletions
+9 -11
View File
@@ -273,7 +273,7 @@ export class Component<T extends Env, Props extends {}, State extends {}> {
if (this.__owl__.isMounted) { if (this.__owl__.isMounted) {
return; return;
} }
if (!this.__owl__.vnode ) { if (!this.__owl__.vnode) {
// we use the fact that renderId === 1 as a way to determine that the // we use the fact that renderId === 1 as a way to determine that the
// component is mounted for the first time // component is mounted for the first time
const vnode = await this.__prepare(); const vnode = await this.__prepare();
@@ -297,20 +297,17 @@ export class Component<T extends Env, Props extends {}, State extends {}> {
} }
} }
async render(force: boolean = false, patchQueue?: any[], scope?: any, vars?: any): Promise<void> { async render(force: boolean = false): Promise<void> {
const __owl__ = this.__owl__; const __owl__ = this.__owl__;
if (!__owl__.isMounted) { if (!__owl__.isMounted) {
return; return;
} }
const shouldPatch: boolean = !patchQueue; const patchQueue = [];
if (shouldPatch) {
patchQueue = [];
}
__owl__.renderId++
const renderId = __owl__.renderId;
await this.__render(force, patchQueue, scope, vars);
if (shouldPatch && __owl__.isMounted && renderId === __owl__.renderId) { const renderId = ++__owl__.renderId;
await this.__render(force, patchQueue, undefined, undefined);
if (__owl__.isMounted && renderId === __owl__.renderId) {
// we only update the vnode and the actual DOM if no other rendering // we only update the vnode and the actual DOM if no other rendering
// occurred between now and when the render method was initially called. // occurred between now and when the render method was initially called.
this.__applyPatchQueue(<any[]>patchQueue); this.__applyPatchQueue(<any[]>patchQueue);
@@ -456,7 +453,7 @@ export class Component<T extends Env, Props extends {}, State extends {}> {
} }
await this.willUpdateProps(nextProps); await this.willUpdateProps(nextProps);
this.props = nextProps; this.props = nextProps;
await this.render(forceUpdate, patchQueue, scope, vars); await this.__render(forceUpdate, patchQueue, scope, vars);
} }
} }
@@ -513,6 +510,7 @@ export class Component<T extends Env, Props extends {}, State extends {}> {
} }
__owl__.render = qweb.render.bind(qweb, this.template); __owl__.render = qweb.render.bind(qweb, this.template);
this.__observeState(); this.__observeState();
return this.__render(false, [], scope, vars); return this.__render(false, [], scope, vars);
} }
@@ -1,5 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`default props default values are also set whenever component is updated 1`] = `"<div>1</div>"`;
exports[`default props default values are also set whenever component is updated 2`] = `"<div>4</div>"`;
exports[`props validation props are validated in dev mode (code snapshot) 1`] = ` exports[`props validation props are validated in dev mode (code snapshot) 1`] = `
"function anonymous(context,extra "function anonymous(context,extra
) { ) {
+8
View File
@@ -327,9 +327,17 @@ describe("default props", () => {
class TestWidget extends Widget { class TestWidget extends Widget {
static defaultProps = { p: 4 }; static defaultProps = { p: 4 };
} }
env.qweb.addTemplates(`
<templates>
<div t-name="TestWidget"><t t-esc="props.p"/></div>
</templates>`);
const w = new TestWidget(env, { p: 1 }); const w = new TestWidget(env, { p: 1 });
await w.mount(fixture);
expect(fixture.innerHTML).toMatchSnapshot();
await w.__updateProps({}); await w.__updateProps({});
await w.render();
expect(w.props.p).toBe(4); expect(w.props.p).toBe(4);
expect(fixture.innerHTML).toMatchSnapshot();
}); });
}); });
+3
View File
@@ -818,9 +818,11 @@ describe("connected components and default values", () => {
expect(fixture.innerHTML).toBe("<div><div>Hello, John</div></div>"); expect(fixture.innerHTML).toBe("<div><div>Hello, John</div></div>");
await app.__updateProps({ initialRecipient: "James" }, true); await app.__updateProps({ initialRecipient: "James" }, true);
await app.render();
expect(fixture.innerHTML).toBe("<div><div>Hello, James</div></div>"); expect(fixture.innerHTML).toBe("<div><div>Hello, James</div></div>");
await app.__updateProps({ initialRecipient: undefined }, true); await app.__updateProps({ initialRecipient: undefined }, true);
await app.render();
expect(fixture.innerHTML).toBe("<div><div>Hello, John</div></div>"); expect(fixture.innerHTML).toBe("<div><div>Hello, John</div></div>");
}); });
@@ -903,6 +905,7 @@ describe("connected components and default values", () => {
); );
await app.__updateProps({ threadId: 2 }, true); await app.__updateProps({ threadId: 2 }, true);
await app.render();
expect(fixture.innerHTML).toBe("<div><div><div>200Message200</div></div></div>"); expect(fixture.innerHTML).toBe("<div><div><div>200Message200</div></div></div>");
store.commit("changeMessageContent", 200, "UpdatedMessage200"); store.commit("changeMessageContent", 200, "UpdatedMessage200");