有没有办法在TypeScript中挂钩类的声明过程?
e.g。考虑以下课程
class Foo extends Bar
{
constructor() { super(); }
}
我目前通过手动调用weaver来将方面应用于此类型:
weaver.applyAspects(Foo);
这意味着我修改了类中某些方法的行为。 我宁愿看到这只是通过在上面的例子中继承“Bar”超级类而自动发生。
在构造函数中做一些时髦的东西似乎是错误的,因为这将适用于每个新实例,而不仅仅是原型本身。
我想我可以覆盖__extends函数(在生成的javascript输出中使用),但这看起来有点时髦。
还有其他选择吗?
答案 0 :(得分:3)
如果要在TypeScript中使用AOP,可以通过为现有AOP框架提供定义来使用它。这是一个使用jQuery.aop的完整示例。
以这种方式使用AOP不会影响任何现有定义,因为AOP代码在您交叉的代码上是不可见的。
aop.d.ts
declare class Advice {
unweave(): void;
}
declare interface PointCut {
target: Object;
method: string;
}
declare class Aop {
before: (pointCut: PointCut, advice: Function) => Advice[];
after: (pointCut: PointCut, advice: Function) => Advice[];
afterThrow: (pointCut: PointCut, advice: Function) => Advice[];
afterFinally: (pointCut: PointCut, advice: Function) => Advice[];
around: (pointCut: PointCut, advice: Function) => Advice[];
introduction: (pointCut: PointCut, advice: Function) => Advice[];
}
interface JQueryStatic {
aop: Aop;
}
app.ts
/// <reference path="jquery.d.ts" />
/// <reference path="aop.d.ts" />
class ExampleClass {
exampleMethod() {
alert('Hello');
}
}
jQuery.aop.before(
{ target: ExampleClass, method: 'exampleMethod' },
function () { alert('Before exampleMethod'); }
);
jQuery.aop.after(
{ target: ExampleClass, method: 'exampleMethod' },
function () { alert('After exampleMethod'); }
);
var example = new ExampleClass();
example.exampleMethod();
示例来源:AOP with TypeScript。
<强>更新强>
要向类和所有兼容类添加相同的关注点,您不能重用基类点。这是因为包装器是包含在点中的原始基类函数,这将是扩展基类的类的错误实现。
这个唯一有效的时间是你的函数只调用super()
,在这种情况下它会起作用。
以下是我将如何将相同的问题添加到许多类中 - AopHelper只需要在程序中存在一次:
/// <reference path="jquery.d.ts" />
/// <reference path="aop.d.ts" />
class ExampleClass {
exampleMethod() {
alert('Hello');
}
}
class SecondClass extends ExampleClass {
exampleMethod() {
alert('World');
}
}
class AopHelper {
static weave(targets: Object[], method: string, point: Function, advice: Function) {
for (var i = 0; i < targets.length; i++) {
point({ target: targets[i], method: method }, advice );
}
}
}
var classes: any[] = [ExampleClass, SecondClass];
AopHelper.weave(classes, 'exampleMethod', jQuery.aop.before, () => { alert('Before exampleMethod'); });
AopHelper.weave(classes, 'exampleMethod', jQuery.aop.after, () => { alert('After exampleMethod'); });
var example = new SecondClass();
example.exampleMethod();
答案 1 :(得分:0)
https://github.com/agentframework/agentframework
这是TypeScript的另一个AOP使用最新的装饰器功能。
您可以使用装饰器
添加自己的拦截器让我们说以下是您想要的行为
class Directory {
public getRoot(): string {
try {
return this._root.path;
}
catch(err) {
return null;
}
}
}
您可以在AgentFramework
中执行以下操作@agent('DirAgent')
class Directory {
@failure(null)
public getRoot(): string {
return this._root.path;
}
}
@failure(null)是一个开箱即用的属性,当方法抛出错误时,它将返回给定值null
。你也可以改成@failure(''),@ failure(0),@ failure(false)来使你的代码更具可读性。
答案 2 :(得分:0)
为了在打字稿中成功实施AOP技术,我建议使用kaop-ts
同时检查此answer
class Component extends SomeOtherComponent {
...
@beforeMethod(YourHttpService.getCached, '/url/to/html')
@beforeMethod(YourHtmlParser.template)
invalidate (parsedHtml?: any) {
this.element.append(parsedHtml)
}
}
...
componentInstance.invalidate()
// explanation below