[IMP[ component/hooks: add onWillStart and onWillUpdateProps

This commit is contained in:
Géry Debongnie
2019-10-09 15:09:26 +02:00
parent 5f6f081ae2
commit 07dac970f7
3 changed files with 68 additions and 4 deletions
+9 -2
View File
@@ -86,6 +86,8 @@ interface Internal<T extends Env, Props> {
willUnmountCB: Function | null;
willPatchCB: Function | null;
patchedCB: Function | null;
willStartCB: Function | null;
willUpdatePropsCB: Function | null;
classObj: { [key: string]: boolean } | null;
refs: { [key: string]: Component<T, any> | HTMLElement | undefined } | null;
}
@@ -192,6 +194,8 @@ export class Component<T extends Env, Props extends {}> {
willUnmountCB: null,
willPatchCB: null,
patchedCB: null,
willStartCB: null,
willUpdatePropsCB: null,
observer: null,
render: qweb.render.bind(qweb, this.__getTemplate(qweb)),
classObj: null,
@@ -510,7 +514,10 @@ export class Component<T extends Env, Props extends {}> {
if (defaultProps) {
nextProps = this.__applyDefaultProps(nextProps, defaultProps);
}
await this.willUpdateProps(nextProps);
await Promise.all([
this.willUpdateProps(nextProps),
this.__owl__.willUpdatePropsCB && this.__owl__.willUpdatePropsCB(nextProps)
]);
this.props = nextProps;
const fiber = this.__createFiber(parentFiber.force, scope, vars, parentFiber);
fiber.patchQueue.push(fiber);
@@ -566,7 +573,7 @@ export class Component<T extends Env, Props extends {}> {
}
async __prepareAndRender(fiber: Fiber<Props>): Promise<VNode> {
try {
await this.willStart();
await Promise.all([this.willStart(), this.__owl__.willStartCB && this.__owl__.willStartCB()]);
} catch (e) {
errorHandler(e, this);
return Promise.resolve(h("div"));
+18 -2
View File
@@ -64,11 +64,28 @@ function makeLifecycleHook(method: string, reverse: boolean = false) {
}
}
function makeAsyncHook(method: string) {
return function(cb) {
const component: Component<any, any> = Component._current;
if (component.__owl__[method]) {
const current = component.__owl__[method];
component.__owl__[method] = function(...args) {
return Promise.all[(current.call(component, ...args), cb.call(component, ...args))];
};
} else {
component.__owl__[method] = cb;
}
};
}
export const onMounted = makeLifecycleHook("mountedCB", true);
export const onWillUnmount = makeLifecycleHook("willUnmountCB");
export const onWillPatch = makeLifecycleHook("willPatchCB");
export const onPatched = makeLifecycleHook("patchedCB", true);
export const onWillStart = makeAsyncHook("willStartCB");
export const onWillUpdateProps = makeAsyncHook("willUpdatePropsCB");
// -----------------------------------------------------------------------------
// useRef
// -----------------------------------------------------------------------------
@@ -100,7 +117,6 @@ export function useRef(name: string): Ref {
// useSubEnv
// -----------------------------------------------------------------------------
/**
* This hook is a simple way to let components use a sub environment. Note that
* like for all hooks, it is important that this is only called in the
@@ -109,4 +125,4 @@ export function useRef(name: string): Ref {
export function useSubEnv(nextEnv) {
const component = Component._current;
component.env = Object.assign(Object.create(component.env), nextEnv);
}
}