[FIX] bind lifecycle callbacks to component

Before this commit, some of the callbacks were bound to the component
and some were not.
This commit makes all the callbacks bind to the component.
This commit is contained in:
Michael (mcm)
2022-01-18 14:54:58 +01:00
committed by Géry Debongnie
parent 83d38a6f48
commit 057e6944d6
3 changed files with 89 additions and 10 deletions
+10 -10
View File
@@ -7,44 +7,44 @@ import { nodeErrorHandlers } from "./error_handling";
export function onWillStart(fn: () => Promise<void> | void | any) {
const node = getCurrent()!;
node.willStart.push(fn);
node.willStart.push(fn.bind(node.component));
}
export function onWillUpdateProps(fn: (nextProps: any) => Promise<void> | void | any) {
const node = getCurrent()!;
node.willUpdateProps.push(fn);
node.willUpdateProps.push(fn.bind(node.component));
}
export function onMounted(fn: () => void | any) {
const node = getCurrent()!;
node.mounted.push(fn);
node.mounted.push(fn.bind(node.component));
}
export function onWillPatch(fn: () => Promise<void> | any | void) {
const node = getCurrent()!;
node.willPatch.unshift(fn);
node.willPatch.unshift(fn.bind(node.component));
}
export function onPatched(fn: () => void | any) {
const node = getCurrent()!;
node.patched.push(fn);
node.patched.push(fn.bind(node.component));
}
export function onWillUnmount(fn: () => Promise<void> | void | any) {
const node = getCurrent()!;
node.willUnmount.unshift(fn);
node.willUnmount.unshift(fn.bind(node.component));
}
export function onWillDestroy(fn: () => Promise<void> | void | any) {
const node = getCurrent()!;
node.willDestroy.push(fn);
node.willDestroy.push(fn.bind(node.component));
}
export function onWillRender(fn: () => void | any) {
const node = getCurrent()!;
const renderFn = node.renderFn;
node.renderFn = () => {
fn();
fn.call(node.component);
return renderFn();
};
}
@@ -54,7 +54,7 @@ export function onRendered(fn: () => void | any) {
const renderFn = node.renderFn;
node.renderFn = () => {
const result = renderFn();
fn();
fn.call(node.component);
return result;
};
}
@@ -67,5 +67,5 @@ export function onError(callback: OnErrorCallback) {
handlers = [];
nodeErrorHandlers.set(node, handlers);
}
handlers.push(callback);
handlers.push(callback.bind(node.component));
}
@@ -187,6 +187,28 @@ exports[`lifecycle hooks hooks are called in proper order in widget creation/des
}"
`;
exports[`lifecycle hooks lifecycle callbacks are bound to component 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return component(\`Test\`, {rev: ctx['rev']}, key + \`__1\`, node, ctx);
}
}"
`;
exports[`lifecycle hooks lifecycle callbacks are bound to component 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['props'].rev);
}
}"
`;
exports[`lifecycle hooks lifecycle semantics 1`] = `
"function anonymous(bdom, helpers
) {
+57
View File
@@ -5,10 +5,13 @@ import {
onPatched,
onWillUpdateProps,
onWillRender,
onWillDestroy,
onRendered,
} from "../../src/component/lifecycle_hooks";
import { status } from "../../src/component/status";
import {
elem,
logStep,
makeDeferred,
makeTestFixture,
nextTick,
@@ -1196,4 +1199,58 @@ describe("lifecycle hooks", () => {
expect(["Parent:willPatch", "Parent:patched"]).toBeLogged();
expect(fixture.innerHTML).toBe("<span>Patched</span>");
});
test("lifecycle callbacks are bound to component", async () => {
expect.assertions(14);
let instance: any;
class Test extends Component {
static template = xml`<t t-esc="props.rev" />`;
setup() {
instance = this;
onWillStart(this.logger("onWillStart"));
onMounted(this.logger("onMounted"));
onWillUpdateProps(this.logger("onWillUpdateProps"));
onWillPatch(this.logger("onWillPatch"));
onPatched(this.logger("onPatched"));
onWillUnmount(this.logger("onWillUnmount"));
onWillDestroy(this.logger("onWillDestroy"));
onWillRender(this.logger("onWillRender"));
onRendered(this.logger("onRendered"));
}
logger(hookName: string) {
return function (this: Test) {
logStep(hookName);
expect(this === instance).toBe(true);
};
}
}
class Parent extends Component {
static template = xml`<Test rev="rev" />`;
static components = { Test };
rev = 0;
}
const app = new App(Parent);
const comp = await app.mount(fixture);
comp.rev++;
comp.render();
await nextTick();
app.destroy();
expect([
"onWillStart",
"onWillRender",
"onRendered",
"onMounted",
"onWillUpdateProps",
"onWillRender",
"onRendered",
"onWillPatch",
"onPatched",
"onWillUnmount",
"onWillDestroy",
]).toBeLogged();
});
});