mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: can mount on different target without unmounting
closes #616
This commit is contained in:
@@ -302,8 +302,15 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
const position = options.position || "last-child";
|
const position = options.position || "last-child";
|
||||||
const __owl__ = this.__owl__;
|
const __owl__ = this.__owl__;
|
||||||
if (__owl__.isMounted) {
|
if (__owl__.isMounted) {
|
||||||
|
if (position !== "self" && this.el!.parentNode !== target) {
|
||||||
|
// in this situation, we are trying to mount a component on a different
|
||||||
|
// target. In this case, we need to unmount first, otherwise it will
|
||||||
|
// not work.
|
||||||
|
this.unmount();
|
||||||
|
} else {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!(target instanceof HTMLElement || target instanceof DocumentFragment)) {
|
if (!(target instanceof HTMLElement || target instanceof DocumentFragment)) {
|
||||||
let message = `Component '${this.constructor.name}' cannot be mounted: the target is not a valid DOM node.`;
|
let message = `Component '${this.constructor.name}' cannot be mounted: the target is not a valid DOM node.`;
|
||||||
message += `\nMaybe the DOM is not ready yet? (in that case, you can use owl.utils.whenReady)`;
|
message += `\nMaybe the DOM is not ready yet? (in that case, you can use owl.utils.whenReady)`;
|
||||||
|
|||||||
@@ -376,4 +376,34 @@ describe("unmounting and remounting", () => {
|
|||||||
expect(fixture.innerHTML).toBe("");
|
expect(fixture.innerHTML).toBe("");
|
||||||
expect(Child.prototype.__render).toBeCalledTimes(1);
|
expect(Child.prototype.__render).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("widget can be mounted on different target", async () => {
|
||||||
|
const steps: string[] = [];
|
||||||
|
class MyWidget extends Component<any, any> {
|
||||||
|
static template = xml`<div>Hey</div>`;
|
||||||
|
async willStart() {
|
||||||
|
steps.push("willstart");
|
||||||
|
}
|
||||||
|
mounted() {
|
||||||
|
steps.push("mounted");
|
||||||
|
}
|
||||||
|
willUnmount() {
|
||||||
|
steps.push("willunmount");
|
||||||
|
}
|
||||||
|
patched() {
|
||||||
|
throw new Error("patched should not be called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const div = document.createElement("div");
|
||||||
|
const span = document.createElement("span");
|
||||||
|
fixture.appendChild(div);
|
||||||
|
fixture.appendChild(span);
|
||||||
|
const w = new MyWidget();
|
||||||
|
await w.mount(div);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("<div><div>Hey</div></div><span></span>");
|
||||||
|
|
||||||
|
await w.mount(span);
|
||||||
|
expect(fixture.innerHTML).toBe("<div></div><span><div>Hey</div></span>");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user