javascript - Javascript 装饰器监听器
问题描述
我正在和装饰器混在一起,有一个 Angular 背景,我正试图将我的头包裹在HostListener
装饰器周围。
这是我走了多远:
class Demo {
counter = 0;
@Listen("mousemove") onMouseMove(e?) {
console.log(this);
this.counter++;
}
}
export function Listen(name) {
return (target, key, descriptor) => {
window.addEventListener(name, oldValue.bind(target));
return descriptor;
};
}
new Demo();
这或多或少是实现唯一的问题是传递目标/此引用,因为目标未初始化。
解决方案
解决了,我正在使用 Vue,所以这可能不是每个人的答案,基本上我正在做的是在 Vue 中调用该函数一次,您可以添加一个 mixin,并且在这个 mixinbeforeMount
中将调用钩子,从而允许我在这里调用一次。
装饰器更新代码:
export function Listen(name) {
return function (target, key, descriptor) {
if (!target.subscriptions) target.subscriptions = [];
add(target, "Listen", key);
if (process.client) {
const oldValue = descriptor.value;
descriptor.value = function() {
target.subscriptions.push(
target.$eventManager.add(window, name, oldValue.bind(this))
);
};
return descriptor;
}
return descriptor;
};
}
const add = (target, name, functionName) => {
if(!target.decorators) target.decorators = {};
if(!target.decorators[name]) target.decorators[name] = [];
target.decorators[name].push(functionName);
};
Vue 混合:
Vue.mixin({
beforeMount: function() {
if(this.decorators && this.decorators.Listen) {
this.decorators.Listen.forEach(key => this[key]());
}
},
destroyed: function () {
this.$subscriptionManager.remove(this.subscriptions);
}
});
推荐阅读
- python - Python 次要版本之间的轮子不兼容
- c# - 使用系统有什么好处。诊断。开关?
- javascript - 如何在字符串模板中放置链接?
- java - 可以定义 Java 接口,使得只有 Enums 可以扩展它吗?
- css - 在不同屏幕宽度的容器中堆叠响应式图像
- sql - 合并具有 NULL 值的数据集
- java - 图像未在 JasperReport 电子邮件模板中加载
- android - CardView 没有包装多行 EditText
- multithreading - 是否可以仅使用 std 访问具有多个线程的不相交切片?
- vue.js - V-for 3000+ 记录加载真的很慢(12+ 秒)