[FIX] component: can mount on different target without unmounting

closes #616
This commit is contained in:
Géry Debongnie
2020-01-18 09:33:03 +01:00
committed by aab-odoo
parent f9cac94dc7
commit 1c8dc97fca
2 changed files with 38 additions and 1 deletions
+8 -1
View File
@@ -302,7 +302,14 @@ export class Component<T extends Env, Props extends {}> {
const position = options.position || "last-child";
const __owl__ = this.__owl__;
if (__owl__.isMounted) {
return Promise.resolve();
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();
}
}
if (!(target instanceof HTMLElement || target instanceof DocumentFragment)) {
let message = `Component '${this.constructor.name}' cannot be mounted: the target is not a valid DOM node.`;
+30
View File
@@ -376,4 +376,34 @@ describe("unmounting and remounting", () => {
expect(fixture.innerHTML).toBe("");
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>");
});
});