Angular 4:@Inject何时以及为什么在构造函数中使用?

Vik*_*sal 22 javascript constructor angular-material2 angular

问题陈述

我正在学习Angular 4,我偶然发现了一个代码,@Inject它正在被用于a中constructor,我无法弄清楚为什么......

代码和来源

我正在使用Angular 4 Material

代码来源: https ://material.angular.io/components/dialog/overview

在代码中,它们正在注入 MAT_DIALOG_DATA

constructor(public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
             @Inject(MAT_DIALOG_DATA) public data: any
           ) { }
Run Code Online (Sandbox Code Playgroud)

任何人都可以详细说明它的意思,我们应该在何时/何地这样做?

Rah*_*ngh 9

@Inject()是一种手动机制,让Angular知道必须注入一个 参数.

import { Component, Inject } from '@angular/core';
import { ChatWidget } from '../components/chat-widget';

@Component({
  selector: 'app-root',
  template: `Encryption: {{ encryption }}`
})
export class AppComponent {
  encryption = this.chatWidget.chatSocket.encryption;

  constructor(@Inject(ChatWidget) private chatWidget) { }
}
Run Code Online (Sandbox Code Playgroud)

在上面我们要求通过调用chatWidget成为单身Angular与class符号ChatWidget的 关联@Inject(ChatWidget).重要的是要注意我们正在使用 ChatWidget它的打字作为其单身人士的参考.我们使用ChatWidget实例什么,角确实为我们在幕后

来自https://angular-2-training-book.rangle.io/handout/di/angular2/inject_and_injectable.html


eko*_*eko 7

如果MAT_DIALOG_DATA是非工厂/类依赖(如string您的配置),通常使用@Inject.

另请查看InjectionToken:https://angular.io/guide/dependency-injection#injectiontoken

为非类依赖项选择提供者令牌的一种解决方案是定义和使用 InjectionToken


这是一个吸烟者:http://plnkr.co/edit/GAsVdGfeRpASiBEy66Pu?p =preview

如果您@Inject在这些情况下删除,您将收到一个

无法解析ComponentName的所有参数:(?)


Yil*_*ric 7

Angular 中的 IoC 容器使用构造函数中的类型声明来确定要注入构造函数参数的对象。

在您的示例中,“ public data: any” 参数无法由其类型声明确定,因为它被定义为“any”。为了解决这个问题,你必须使用“ @Inject(MAT_DIALOG_DATA)”装饰器来通知IoC容器必须注入“ data”参数的对象。

同样在您的示例中,“ @Inject” 装饰器与 anInjectionToken一起使用使事情变得更加复杂:)

AnInjectionToken实际上是一个类,用于命名 IoC 容器使用的对象以注入其他类。通常,您可以使用任何类名作为 IoC 注入的标记(例如MatDialogRef<DialogOverviewExampleDialog>您的示例中的“ ”),这很好用。但是当你开始编写你的单元测试时,你意识到你需要使用 Mock 对象而不是真实的对象来注入你的类,当你使用真实的类名作为你的标记时,你不能这样做。

要解决这个问题,您可以将Interfaces名称用作标记名称,这实际上是正确的解决方案,但是由于 JavaScript 不支持接口,因此您不能将Interface名称用作标记,因为转译的代码不包含Interface定义。

因此,您需要使用InjectionToken. AnInjectionToken允许您将任何对象注入到构造函数中。你只需要在你的模块中声明它并映射到你想要注入的真实类。这样你就可以为你的生产和测试代码使用不同的类。