[ADD] hooks: add useExternalListener hook

It is very useful.

Also, this commit prettifies the code.

closes #608
This commit is contained in:
Géry Debongnie
2020-01-09 10:02:27 +01:00
parent 0c9c5b877b
commit 54f5819ef9
8 changed files with 147 additions and 59 deletions
+24
View File
@@ -131,3 +131,27 @@ export function useSubEnv(nextEnv) {
const component = Component.current!;
component.env = Object.assign(Object.create(component.env), nextEnv);
}
// -----------------------------------------------------------------------------
// useExternalListener
// -----------------------------------------------------------------------------
/**
* When a component needs to listen to DOM Events on element(s) that are not
* part of his hierarchy, we can use the `useExternalListener` hook.
* It will correctly add and remove the event listener, whenever the
* component is mounted and unmounted.
*
* Example:
* a menu needs to listen to the click on window to be closed automatically
*
* Usage:
* in the constructor of the OWL component that needs to be notified,
* `useExternalListener(window, 'click', this._doSomething);`
* */
export function useExternalListener(target: HTMLElement, eventName: string, handler, eventParams?) {
const boundHandler = handler.bind(Component.current);
onMounted(() => target.addEventListener(eventName, boundHandler, eventParams));
onWillUnmount(() => target.removeEventListener(eventName, boundHandler, eventParams));
}
+15 -11
View File
@@ -1,4 +1,4 @@
import { compileExpr , compileExprToArray , QWebVar } from "./expression_parser";
import { compileExpr, compileExprToArray, QWebVar } from "./expression_parser";
export const INTERP_REGEXP = /\{\{.*?\}\}/g;
//------------------------------------------------------------------------------
@@ -161,16 +161,18 @@ export class CompilationContext {
const argId = this.generateID();
const tokens = compileExprToArray(expr, this.variables);
const done = new Set();
return tokens.map((tok) => {
if (tok.varName) {
if (!done.has(tok.varName)) {
done.add(tok.varName);
this.addLine(`const ${tok.varName}_${argId} = ${tok.value};`);
return tokens
.map(tok => {
if (tok.varName) {
if (!done.has(tok.varName)) {
done.add(tok.varName);
this.addLine(`const ${tok.varName}_${argId} = ${tok.value};`);
}
tok.value = `${tok.varName}_${argId}`;
}
tok.value = `${tok.varName}_${argId}`;
}
return tok.value;
}).join("");
return tok.value;
})
.join("");
}
/**
@@ -194,7 +196,9 @@ export class CompilationContext {
const protectID = this.generateID();
this.rootContext.protectedScopeNumber++;
this.rootContext.shouldDefineScope = true;
const scopeExpr = codeBlock ? `Object.create(scope);` : `Object.assign(Object.create(context), scope);`;
const scopeExpr = codeBlock
? `Object.create(scope);`
: `Object.assign(Object.create(context), scope);`;
this.addLine(`let _origScope${protectID} = scope;`);
this.addLine(`scope = ${scopeExpr}`);
return protectID;
+3 -1
View File
@@ -283,5 +283,7 @@ export function compileExprToArray(expr: string, scope: { [key: string]: QWebVar
}
export function compileExpr(expr: string, scope: { [key: string]: QWebVar }): string {
return compileExprToArray(expr, scope).map(t => t.value).join("");
return compileExprToArray(expr, scope)
.map(t => t.value)
.join("");
}