更新资料


此问题已打开的问题https://github.com/angular/angular/issues/34721


介绍

在Angular Services中,使用装饰器@Injectable提供。

@Injectable() // -> works
export class MyService {
  constructor() {}
}


@Injectable抽象

在Ivy之前,可以为@Injectable构建抽象(例如,用于动态配置提供程序,增强服务类)。

以下代码段显示了如何包装@Injectable的示例。

function InjectableEnhanced() {
  return <T extends new (...args: any[]) => InstanceType<T>>(target: T) => {
    Injectable({ providedIn: "root" })(target);
  };
}


启用常春藤时,不能使用装饰器InjectableEnhanced(请参见上文)。
截断以下代码会导致运行时错误。

@InjectableEnhanced() // -> does not work
export class MyService {
  constructor() {}
}


运行时错误

使用@InjectableEnhanced与angular / cli一起编译服务有效,但是在浏览器中显示以下错误。相应的项目可以在https://github.com/GregOnNet/ng-9-inject.git中找到。

angular - 用Angular Ivy提取@Injectable不起作用-LMLPHP

也许Angular编译器进行了一些代码转换,但无法再解析其他装饰器中的@Injectable。
看一下角度存储库后,可以在injectable.ts中找到对JIT编译器的引用(请参阅:https://github.com/angular/angular/blob/master/packages/core/src/di/injectable.ts#L14)。



还有抽象@Injectable的方法吗?

复制库

https://github.com/GregOnNet/ng-9-inject.git

最佳答案

可以使用angular的一些内部API创建自定义提供程序:

import { ɵɵdefineInjectable, ɵɵinject } from "@angular/core";

export function InjectableEnhanced() {
  return <T extends new (...args: any[]) => InstanceType<T>>(target: T) => {
    (target as any).ɵfac = function() {
      throw new Error("cannot create directly");
    };

    (target as any).ɵprov = ɵɵdefineInjectable({
      token: target,
      providedIn: "root",
      factory() {
        // ɵɵinject can be used to get dependency being already registered
        const dependency = ɵɵinject(Dependency);
        return new target(dependency);
      }
    });
    return target;
  };
}


工作示例可以在https://github.com/GregOnNet/ng-9-inject中找到

09-25 15:58