【发布时间】:2020-01-19 13:55:21
【问题描述】:
我想实现一个@listen(eventType) 装饰器工厂。当您希望在触发eventType 时调用该方法时,它将返回一个装饰器,您可以将其放置在 Web 组件类的方法上。
用法
class MyElement extends HTMLElement {
//...
@listen('click')
log() {
console.log('log');
}
}
每次单击组件实例时,上面的代码都会将“日志”打印到控制台。
实施思路
在类构造函数中添加对addEventListener 的调用,并将disconnectedCallback 的当前定义替换为调用removeEventListener 的disconnectedCallback 版本,以避免内存泄漏。
实施
export function listen (
eventName,
) {
return function (
proto,
methodName,
descriptor
) {
// add listener when element is constructed
const oldConstructor= proto.constructor;
proto.constructor = function (...args) {
this.addEventListener(eventType, descriptor.value);
return oldConstructor.apply(this, ...args);
};
// remove listener to avoid leaking memory
const oldDisconnectedCallback = proto.disconnectedCallback;
proto.disconnectedCallback = function (...args) {
this.removeEventListener(eventType, descriptor.value);
return oldChange.apply(this, ...args);
};
};
}
尽管方法替换技巧适用于 disconnectedCallback(和任何其他)方法,但它不适用于构造函数。
REPL
这是一个交互式版本的实现:https://stackblitz.com/edit/lit-element-hello-world-ec1lwz?file=listen.js
【问题讨论】:
-
你不需要像那样清理听众。浏览器会同时收集元素和监听器。
标签: typescript decorator web-component typescript-decorator