如何在 CodePen 上向 Angular7 应用程序添加指令

How to add Directive to Angular7 app on CodePen

我正在学习 angular,我正在关注 Udemy 上的教程并查看文档。我是我创造的 Angular app on Codepen

现在我正在尝试定义指令但出现错误:

Uncaught Error: Can't resolve all parameters for PointerDirective: (?).

我的代码如下所示:

@Directive({
    selector: '[pointer]'
})
class PointerDirective implements OnInit {
    constructor(private element: ElementRef) { }
    ngOnInit() { }   
}

@NgModule({
  imports: [
      BrowserModule,
      CommonModule
  ],
  declarations: [ PointerDirective, AppComponent ],
  providers: [],
  bootstrap: [ AppComponent ]
})
class AppModule {}

我也尝试过不同的名称(app-pointer)但得到了同样的错误。

笔是基于this one,但在这里它也不起作用。

搜索此错误时我得到的信息表明这可能是循环依赖,但这里我只有简单的指令。怎么了?

编辑:

根据@trichetriche 的说法,代码仅在 CodePen 上不起作用,我是否遗漏了某些文件?如何在没有构建过程的情况下仅使用脚本标签创建基本的 Angular 项目?如何让 Angular 应用程序在 Codepen 中运行?

EDIT2:

所以我想通了:

@Directive({
    selector: '[pointer]'
})
class PointerDirective implements OnInit {
    constructor(@Inject(ElementRef) private element: ElementRef) {
    }
    ngOnInit() { }   
}

如果您知道为什么 CodePen 需要 @Inject 而普通项目不需要 @Inject,请添加答案。

在您的 codepen 示例中,您使用 typescript 作为预处理器,因此您的所有代码都由 typescript 编译。

Angular 具有内置的 DI 系统,该系统严重依赖于我们在 ts 代码中的构造函数中提供的类型。

constructor(private element: ElementRef) { }
                             ^^^^^^^^^^^
                  we have to keep this type after ts compilation

默认情况下,typescript 在编译后不会保留该信息,但我们可以设置一个名为 emitDecoratorMetadata 的选项来保留此类型,例如:

__metadata("design:paramtypes", [ElementRef])

但是codepen似乎没有这样的选项来改变tsconfig.json所以你必须自己提供那个类型给编译版本。

这里有几个选项:

1) 专用 @Inject 装饰器:

constructor(@Inject(ElementRef) private element: ElementRef) {}

2) class 上的静态 parameters 属性 类型:

class PointerDirective implements OnInit {
  constructor(private element: ElementRef) {}

  static parameters = [ ElementRef ]

3)静态ctorParameters方法:

class PointerDirective implements OnInit {
  constructor(private element: ElementRef) {}

  static ctorParameters = () => [{ type: ElementRef }]

Forked Codepen