fix: force children to rerender when env changes

This commit is contained in:
Géry Debongnie
2019-03-21 16:06:06 +01:00
parent 4326d18961
commit ad9fb77458
4 changed files with 39 additions and 14 deletions
+12 -8
View File
@@ -224,11 +224,11 @@ export class Component<
}
}
async render(): Promise<void> {
async render(force: boolean = false): Promise<void> {
if (this.__widget__.isDestroyed) {
return;
}
const renderVDom = this._render();
const renderVDom = this._render(force);
const renderId = this.__widget__.renderId;
const vnode = await renderVDom;
if (renderId === this.__widget__.renderId) {
@@ -281,16 +281,19 @@ export class Component<
}
Object.assign(this.env, nextEnv);
if (this.__widget__.isMounted) {
return this.render();
return this.render(true);
}
}
async updateProps(nextProps: Props): Promise<void> {
if (nextProps === this.__widget__.renderProps) {
async updateProps(
nextProps: Props,
forceUpdate: boolean = false
): Promise<void> {
if (nextProps === this.__widget__.renderProps && !forceUpdate) {
await this.__widget__.renderPromise;
return;
}
const shouldUpdate = this.shouldUpdate(nextProps);
const shouldUpdate = forceUpdate || this.shouldUpdate(nextProps);
return shouldUpdate ? this._updateProps(nextProps) : Promise.resolve();
}
@@ -348,13 +351,14 @@ export class Component<
return this.__widget__.renderPromise;
}
async _render(): Promise<VNode> {
async _render(force: boolean = false): Promise<VNode> {
this.__widget__.renderId++;
const promises: Promise<void>[] = [];
const template = this.inlineTemplate || this.template;
let vnode = this.env.qweb.render(template, this, {
promises,
handlers: this.__widget__.boundHandlers
handlers: this.__widget__.boundHandlers,
forceUpdate: force
});
// this part is critical for the patching process to be done correctly. The
+6 -2
View File
@@ -947,7 +947,9 @@ const widgetDirective: Directive = {
// check if we can reuse current rendering promise
ctx.addIf(`w${widgetID} && w${widgetID}.__widget__.renderPromise`);
ctx.addIf(`w${widgetID}.__widget__.isStarted`);
ctx.addLine(`def${defID} = w${widgetID}.updateProps(props${widgetID});`);
ctx.addLine(
`def${defID} = w${widgetID}.updateProps(props${widgetID}, extra.forceUpdate);`
);
ctx.addElse();
ctx.addLine(`isNew${widgetID} = true`);
ctx.addIf(`props${widgetID} === w${widgetID}.__widget__.renderProps`);
@@ -961,7 +963,9 @@ const widgetDirective: Directive = {
ctx.addIf(`!def${defID}`);
ctx.addIf(`w${widgetID}`);
ctx.addLine(`def${defID} = w${widgetID}.updateProps(props${widgetID});`);
ctx.addLine(
`def${defID} = w${widgetID}.updateProps(props${widgetID}, extra.forceUpdate);`
);
ctx.addElse();
ctx.addLine(
`w${widgetID} = new context.widgets['${value}'](owner, props${widgetID});`