3

有什么方法可以挂钩 TypeScript 中类的声明过程?

例如考虑以下课程

class Foo extends Bar
{
      constructor() { super(); }
}

我目前通过像这样手动调用我的编织器来将方面应用于这种类型:

weaver.applyAspects(Foo);

这意味着我修改了类中某些方法的行为。我宁愿看到这只是通过在上述情况下继承“Bar”超类而自动发生。

在构造函数中做一些时髦的东西似乎是错误的,因为这将适用于每个新实例,而不仅仅是原型本身。

我想我可以覆盖 __extends 函数(在生成的 javascript 输出中使用),但这似乎也有点时髦。

还有其他选择吗?

4

3 回答 3

4

如果你想在 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;
}

应用程序.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();

示例来源:带有 TypeScript 的 AOP

更新

要将相同的关注点添加到类和所有兼容的类中,您不能重用基类点。这是因为包装器是原来的基类函数,包装在点中,这对于扩展基类的类将是错误的实现。

唯一有效的情况是,如果您的函数仅在这种情况下调用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();
于 2012-11-01T15:11:47.530 回答
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) 以使您的代码更具可读性。

于 2016-10-11T04:35:35.530 回答
0

为了在 typescript 中成功实现 AOP 技术,我建议使用kaop-ts

还要检查这个答案

class Component extends SomeOtherComponent {
  ...
  @beforeMethod(YourHttpService.getCached, '/url/to/html')
  @beforeMethod(YourHtmlParser.template)
  invalidate (parsedHtml?: any) {
    this.element.append(parsedHtml)
  }
}
...
componentInstance.invalidate()
// explanation below
于 2017-06-01T08:43:48.700 回答