[FIX] web: fix ComponentWrapper lifecycle on out-of-DOM updates

Previously, updating a component that was mounted out of the DOM would
rerender it and patch it. In owl 1, patched was not called when a
component was mounted outside of the document. This caused crashes when
something done in onPatched depended on something done in onMounted (as
mounted is also not called when not it the DOM, which was handled
correctly by the compatibility layer).

This commit fixes that by ignoring requests to render a component that
is not yet in the DOM as a new render will be initiated anyway when
mounting the component in the document for real.

closes odoo/odoo#89935

X-original-commit: fc6a843abe52cfee084ed476f00a12a8ba1d1669
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
Signed-off-by: Samuel Degueldre <sad@odoo.com>
This commit is contained in:
Samuel Degueldre
2022-04-28 09:00:54 +02:00
parent fa796c76ad
commit f36306c8ff
2 changed files with 9 additions and 3 deletions
@@ -626,6 +626,9 @@ odoo.define('web.OwlCompatibility', function (require) {
}
render() {
if (this.status !== "mounted") {
return;
}
if (this.renderProm) {
this.node.render(true);
return this.renderProm;
@@ -1060,7 +1060,7 @@ odoo.define('web.OwlCompatibilityTests', function (require) {
});
QUnit.test("lifecycle mount in fragment", async function (assert) {
assert.expect(17);
assert.expect(18);
class MyChildComponent extends LegacyComponent {
setup() {
@@ -1077,8 +1077,8 @@ odoo.define('web.OwlCompatibilityTests', function (require) {
MyComponent.components = { MyChildComponent };
const MyWidget = WidgetAdapter.extend({
start() {
let component = new ComponentWrapper(this, MyComponent, {});
return component.mount(this.el);
this.component = new ComponentWrapper(this, MyComponent, {});
return this.component.mount(this.el);
}
});
@@ -1097,6 +1097,9 @@ odoo.define('web.OwlCompatibilityTests', function (require) {
"onRendered MyChildComponent",
]);
await widget.component.update({});
assert.verifySteps([]); // Out of DOM: shouldn't do anything.
widget.$el.appendTo(target);
widget.on_attach_callback();
assert.verifySteps([