【发布时间】:2015-07-11 16:15:47
【问题描述】:
我正在开发一个使用 Angular 1.x 的 Web 应用程序架构,它仍然用于将事物粘合在一起。定义一个新组件相当容易:
class CustomComponent {
constructor(dep1, dep2, dep3) {
this.deps = { dep1, dep2, dep3 };
/* app code */
}
/* link, compile, instance methods, template generators... */
@readonly static $inject = ['dep1', 'dep2', 'dep3'];
}
我想做的是排除注入问题 - 换句话说,我不想每次都编写 this.deps 和 static $inject 代码,而是让它自动生成 - 比如说,用一些东西就像 ES7 中的装饰器一样。然后代码将看起来像以下几行:
@injectionFromCtorComponents
class MyClass {
constructor (dep1, dep2, dep3) {
/* app logic */
}
}
现在,静态部分是可行的,虽然很丑:
const angularInjectAnnotationFromCtor = (target) => {
let regexStr = `^function ${target.name}\\\((.*)\\\)[.\\s\\S]*}$`;
let regex = new RegExp(regexStr, 'gm');
let ctorArgsStr = target.prototype.constructor.toString().replace(regex, '\$1');
let ctorArgs = ctorArgsStr.replace(/ /g, '').split(',');
target.$inject = ctorArgs;
};
但是,保存实例上的构造函数依赖项要复杂得多。我想出了以下内容,尽管它充其量是脆弱的:
const readonly = (target, key, descriptor) => Object.assign(descriptor, { writable: false });
class AngularComponent {
constructor () {
let ctorArgs = [...arguments];
let argNames = ctorArgs.pop();
// let's leave comprehensions out of this :)
this.deps =
argNames.reduce((result, arg, idx) => Object.assign(result, ({ [arg]: ctorArgs[idx] })), {});
}
}
@angularInjectAnnotationFromCtor
class MyClass extends AngularComponent {
constructor (one, two, three) {
super(one, two, three, MyClass.$inject);
}
}
是的,这比我们开始的时候更糟糕......
那么问题来了,谁能提出一个更合理的解决方案?.. 还是我们应该坐下来期待在未来几年内的任何时候 Chrome 中的代理?
【问题讨论】:
标签: javascript angularjs ecmascript-6 ecmascript-2016