Javascript 角度4:构造函数中何时以及为什么使用@Inject?
问题陈述 我正在学习Angular 4,我偶然发现了一个代码,其中Javascript 角度4:构造函数中何时以及为什么使用@Inject?,javascript,angular,constructor,angular-material2,Javascript,Angular,Constructor,Angular Material2,问题陈述 我正在学习Angular 4,我偶然发现了一个代码,其中@Inject正在构造函数中使用,我不知道为什么 代码和源代码 我用的是角4材质 代码来源: 在代码中,他们正在注入MAT\u DIALOG\u数据 constructor(public dialogRef: MatDialogRef<DialogOverviewExampleDialog>, @Inject(MAT_DIALOG_DATA) public data: any
@Inject
正在构造函数中使用,我不知道为什么
代码和源代码
我用的是角4材质
代码来源:
在代码中,他们正在注入MAT\u DIALOG\u数据
constructor(public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
@Inject(MAT_DIALOG_DATA) public data: any
) { }
构造函数(public dialogRef:MatDialogRef,
@注入(MAT_对话框_数据)公共数据:任意
) { }
请任何人详细说明这意味着什么以及我们应该在何时/何地这样做
@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) { }
}
在上面的例子中,我们要求将chatWidget
作为单例
通过调用
@Inject(ChatWidget)
。需要注意的是,我们正在使用
ChatWidget
用于输入和引用其单例。
我们没有使用ChatWidget
来实例化任何东西,Angular是这样做的
这对我们来说是幕后的
从中,如果MAT\u DIALOG\u DATA
是非工厂/类依赖项(如string
用于配置),则通常使用@Inject
同时检查InjectionToken
:
为非类依赖项选择提供者令牌的一个解决方案是定义并使用InjectionToken
这里有一个小插曲:
如果在这些情况下删除@Inject
,您将收到
无法解析ComponentName:(?)的所有参数
Angular中的IoC容器使用构造函数中的类型声明来确定要注入构造函数参数的对象
在您的示例中,“公共数据:any
”参数的类型声明无法确定,因为它被定义为“any”。为了解决这个问题,您必须使用“@Inject(MAT\u DIALOG\u DATA)
”装饰器通知IoC容器必须注入到“DATA
”参数的对象
同样在您的示例中,“@Inject
”decorator与InjectionToken一起使用,使事情变得更复杂:)
InjectionToken
实际上是一个类,用于命名IoC容器用于注入到其他类中的对象。通常,您可以使用任何类名称作为IoC注入的标记(如示例中的“MatDialogRef
”),这很好。但是,当您开始编写单元测试时,您意识到需要使用模拟对象而不是真实对象来注入到类中,而当您使用真实的类名作为标记时,您无法做到这一点
要解决这个问题,您可以使用接口
作为令牌名称,这实际上是正确的解决方案,但由于JavaScript不支持接口,您不能使用接口
名称作为令牌,因为传输的代码不包含接口
定义
因此,您需要使用InjectionToken
。InjectionToken
允许您将任何对象注入构造函数。您只需要在模块中声明它,并映射到要注入的实际类。通过这种方式,您可以为生产代码和测试代码使用不同的类。注入ChatWidget
组件,使组件的行为类似于单例服务
,以便组件状态在整个应用程序中保持不变。是动机吗?我明白了吗?@VikasBansal Rahul是对的,但这里不是这样,即使这里没有使用@Inject
,并且服务是在根级别提供的,服务仍然是单例的。如果你阅读了这个答案中链接下方的段落,你会发现它没有什么区别。不是组件,而是利用组件中的单例服务
。如果将其放置在根级别,它将在整个应用程序中表现为单例,否则仅在组件级别上。我认为它不会向下延伸到子组件。AngularJS中的componentoC容器是单例的,我想这只是注入令牌的用例之一,您也可以使用注入令牌将参数传递给您的服务谢谢您的回答,示例plunker非常有用!我想知道为什么我们要使用InjectionToken
而不是我们可以从另一个共享文件中要求的简单常量?或者甚至可能只是组件上定义的变量?@philipyoo 1原因可能是您可能希望替换使用注入令牌的服务。另一种是模块化方法;您可以通过.forRoot()传递config选项,并通过Inject在类中使用它们