mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component can be updated while detached from the main DOM
This commit tries to improve the interactions involving unmounted components, or components mounted in an htmelement which is detached from the main DOM, and rendering actions. The main example is mounting a component in detached div, to prepare all children. If we just mount the component, it will work as expected: the full component tree is rendered in memory, and ready to be really mounted at the desired target. However, if before doing that, we update the component and call render on it (for example, with a change in an observed state), then this rendering will be ignored, and therefore, the full subcomponent tree is not uptodate. This commit will also solve another issue in the compatibility layer in odoo: in the form renderer, we mount components with the adapter in a div, which is not yet attached to the DOM. We then manually call the mounted hook when on_attach_callback is called. This means that before this commit, any change to the components between the initial rendering and the call to mounted will be ignored. As a bonus, this commit has the effect of bringing closer the semantics of render and mount operations, which is certainly good. closes #823
This commit is contained in:
+22
-17
@@ -188,7 +188,8 @@ export class Fiber {
|
||||
complete() {
|
||||
let component = this.component;
|
||||
this.isCompleted = true;
|
||||
if (!this.target && !component.__owl__.isMounted) {
|
||||
const { isMounted, isDestroyed } = component.__owl__;
|
||||
if (isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,14 +203,16 @@ export class Fiber {
|
||||
const patchLen = patchQueue.length;
|
||||
|
||||
// call willPatch hook on each fiber of patchQueue
|
||||
for (let i = 0; i < patchLen; i++) {
|
||||
const fiber = patchQueue[i];
|
||||
if (fiber.shouldPatch) {
|
||||
component = fiber.component;
|
||||
if (component.__owl__.willPatchCB) {
|
||||
component.__owl__.willPatchCB();
|
||||
if (isMounted) {
|
||||
for (let i = 0; i < patchLen; i++) {
|
||||
const fiber = patchQueue[i];
|
||||
if (fiber.shouldPatch) {
|
||||
component = fiber.component;
|
||||
if (component.__owl__.willPatchCB) {
|
||||
component.__owl__.willPatchCB();
|
||||
}
|
||||
component.willPatch();
|
||||
}
|
||||
component.willPatch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,16 +274,18 @@ export class Fiber {
|
||||
}
|
||||
|
||||
// call patched/mounted hook on each fiber of (reversed) patchQueue
|
||||
for (let i = patchLen - 1; i >= 0; i--) {
|
||||
const fiber = patchQueue[i];
|
||||
component = fiber.component;
|
||||
if (fiber.shouldPatch && !this.target) {
|
||||
component.patched();
|
||||
if (component.__owl__.patchedCB) {
|
||||
component.__owl__.patchedCB();
|
||||
if (isMounted || inDOM) {
|
||||
for (let i = patchLen - 1; i >= 0; i--) {
|
||||
const fiber = patchQueue[i];
|
||||
component = fiber.component;
|
||||
if (fiber.shouldPatch && !this.target) {
|
||||
component.patched();
|
||||
if (component.__owl__.patchedCB) {
|
||||
component.__owl__.patchedCB();
|
||||
}
|
||||
} else {
|
||||
component.__callMounted();
|
||||
}
|
||||
} else if (this.target ? inDOM : true) {
|
||||
component.__callMounted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user