mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component/hooks: onWillUnmount was not properly called
This commit is contained in:
@@ -437,6 +437,9 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
const __owl__ = this.__owl__;
|
const __owl__ = this.__owl__;
|
||||||
const isMounted = __owl__.isMounted;
|
const isMounted = __owl__.isMounted;
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
|
if (__owl__.willUnmountCB) {
|
||||||
|
__owl__.willUnmountCB();
|
||||||
|
}
|
||||||
this.willUnmount();
|
this.willUnmount();
|
||||||
__owl__.isMounted = false;
|
__owl__.isMounted = false;
|
||||||
}
|
}
|
||||||
@@ -466,7 +469,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
try {
|
try {
|
||||||
this.mounted();
|
this.mounted();
|
||||||
if (__owl__.mountedCB) {
|
if (__owl__.mountedCB) {
|
||||||
__owl__.mountedCB()
|
__owl__.mountedCB();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorHandler(e, this);
|
errorHandler(e, this);
|
||||||
|
|||||||
+76
-2
@@ -78,6 +78,40 @@ describe("hooks", () => {
|
|||||||
expect(steps).toEqual(["mounted", "willunmount"]);
|
expect(steps).toEqual(["mounted", "willunmount"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("can use onMounted, onWillUnmount, part 2", async () => {
|
||||||
|
const steps: string[] = [];
|
||||||
|
function useMyHook() {
|
||||||
|
onMounted(() => {
|
||||||
|
steps.push("mounted");
|
||||||
|
});
|
||||||
|
onWillUnmount(() => {
|
||||||
|
steps.push("willunmount");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
class MyComponent extends Component<any, any> {
|
||||||
|
static template = xml`<div>hey</div>`;
|
||||||
|
constructor(env) {
|
||||||
|
super(env);
|
||||||
|
useMyHook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parent extends Component<any, any> {
|
||||||
|
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
||||||
|
static components = { MyComponent };
|
||||||
|
state = useState({ flag: true });
|
||||||
|
}
|
||||||
|
const parent = new Parent(env);
|
||||||
|
await parent.mount(fixture);
|
||||||
|
expect(fixture.innerHTML).toBe("<div><div>hey</div></div>");
|
||||||
|
expect(steps).toEqual(["mounted"]);
|
||||||
|
|
||||||
|
parent.state.flag = false;
|
||||||
|
await nextTick();
|
||||||
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
|
expect(steps).toEqual(["mounted", "willunmount"]);
|
||||||
|
});
|
||||||
|
|
||||||
test("mounted, willUnmount, onMounted, onWillUnmount order", async () => {
|
test("mounted, willUnmount, onMounted, onWillUnmount order", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
function useMyHook() {
|
function useMyHook() {
|
||||||
@@ -109,6 +143,46 @@ describe("hooks", () => {
|
|||||||
expect(steps).toEqual(["comp:mounted", "hook:mounted", "hook:willunmount", "comp:willunmount"]);
|
expect(steps).toEqual(["comp:mounted", "hook:mounted", "hook:willunmount", "comp:willunmount"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("mounted, willUnmount, onMounted, onWillUnmount order, part 2", async () => {
|
||||||
|
const steps: string[] = [];
|
||||||
|
function useMyHook() {
|
||||||
|
onMounted(() => {
|
||||||
|
steps.push("hook:mounted");
|
||||||
|
});
|
||||||
|
onWillUnmount(() => {
|
||||||
|
steps.push("hook:willunmount");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
class MyComponent extends Component<any, any> {
|
||||||
|
static template = xml`<div>hey</div>`;
|
||||||
|
constructor(env) {
|
||||||
|
super(env);
|
||||||
|
useMyHook();
|
||||||
|
}
|
||||||
|
mounted() {
|
||||||
|
steps.push("comp:mounted");
|
||||||
|
}
|
||||||
|
willUnmount() {
|
||||||
|
steps.push("comp:willunmount");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parent extends Component<any, any> {
|
||||||
|
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
||||||
|
static components = { MyComponent };
|
||||||
|
state = useState({ flag: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const parent = new Parent(env);
|
||||||
|
await parent.mount(fixture);
|
||||||
|
expect(fixture.innerHTML).toBe("<div><div>hey</div></div>");
|
||||||
|
parent.state.flag = false;
|
||||||
|
await nextTick();
|
||||||
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
|
|
||||||
|
expect(steps).toEqual(["comp:mounted", "hook:mounted", "hook:willunmount", "comp:willunmount"]);
|
||||||
|
});
|
||||||
|
|
||||||
test("two different call to mounted/willunmount should work", async () => {
|
test("two different call to mounted/willunmount should work", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
function useMyHook(i) {
|
function useMyHook(i) {
|
||||||
@@ -346,7 +420,7 @@ describe("hooks", () => {
|
|||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component<any, any> {
|
||||||
static template = xml`<div><t t-esc="env.val"/><Child/></div>`;
|
static template = xml`<div><t t-esc="env.val"/><Child/></div>`;
|
||||||
static components = { Child}
|
static components = { Child };
|
||||||
constructor(env) {
|
constructor(env) {
|
||||||
super(env);
|
super(env);
|
||||||
useSubEnv({ val: 3 });
|
useSubEnv({ val: 3 });
|
||||||
@@ -354,6 +428,6 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
const component = new Parent(env);
|
const component = new Parent(env);
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe( "<div>3<div>5</div></div>");
|
expect(fixture.innerHTML).toBe("<div>3<div>5</div></div>");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user