【问题标题】:How to make class decorator which works correct with DI如何制作与 DI 一起工作的类装饰器
【发布时间】:2018-01-20 07:40:18
【问题描述】:

我想装饰我的班级

@params({
  url: '/books'
})
@Injectable()
export class BooksResource {
  constructor(@Inject(HttpClient) protected http: HttpClient) {}
  get() {
    return this.http.get(this.url)
  }
}

通过自定义 @params 装饰器

function params(options) {
  return (target) {
    const original = target;

    function construct(constructor, args) {
      const c: any = function () {
        return constructor.apply(this, args);
      };
      c.prototype = constructor.prototype;
      return new c();
    }

    const newConstructor: any = function (...args) {
      const instance = construct(original, args);

      instance.url = options.url;

      return instance;
    };

    newConstructor.prototype = target.prototype;

    return newConstructor;
  }
}

我用自定义构造函数尝试了一百万种变体,但它们不适用于注入的参数

原始构造函数很好用

function params(options) {
  return (target) {
    return target
  }
}

如何解决? 游乐场:https://embed.plnkr.co/opnY3y/

【问题讨论】:

  • 你想做什么?你想给目标类添加属性吗?
  • 是的。一般来说,当参数被合并时,我想用参数装饰器扩展类。例如:@params({ withCredentials: true }) class Resource {} @params({ url: '/books' }) class BookResource extends Resource {}

标签: angular typescript dependency-injection decorator


【解决方案1】:

Angular 对继承非常严格。我不确定它是否适用于 AOT,但在您的 plunker 中您可以使用以下装饰器:

function params(options) {
  return (target) => {
    const original = target;

    const newConstructor: any = function newCtor(...args) {
      const c: any = function childConstuctor() {
        return original.apply(this, arguments);
      };
      c.prototype = Object.create(original.prototype);
      const instance = new c(...args);

      instance.url = options.url;

      return instance;
    };

    newConstructor.prototype = Object.create(target.prototype);
    return newConstructor;
  }
}

注意:函数名是必需的

Forked Plunker

【讨论】:

  • 它适用于 AOT。为什么需要“newCtor”名称。是因为 Angular 将它用于 DI?
  • @tamtakoe,奇怪。我不应该使用 AOT,因为您在装饰器中使用函数表达式。
猜你喜欢
  • 1970-01-01
  • 2011-11-22
  • 2016-03-06
  • 2014-12-28
  • 2019-03-09
  • 2020-03-26
  • 2017-08-01
  • 2014-04-14
  • 2020-10-04
相关资源
最近更新 更多