代码之家  ›  专栏  ›  技术社区  ›  Vikas Bansal

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

  •  32
  • Vikas Bansal  · 技术社区  · 7 年前

    问题陈述

    我正在学习Angular 4,我偶然发现了一个代码 @Inject 正在用于 constructor 我不知道为什么。。。

    代码和源代码

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

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

    constructor(public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
                 @Inject(MAT_DIALOG_DATA) public data: any
               ) { }
    

    有谁能详细说明这意味着什么以及我们应该在何时/何地这样做?

    3 回复  |  直到 7 年前
        1
  •  10
  •   jonrsharpe    7 年前

    @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 成为单子角 与 class 象征 ChatWidget @Inject(ChatWidget) 聊天工具 因为它的打字 作为一个 给它的单身汉。 我们是 聊天工具 要实例化任何东西,Angular需要

    从…起 https://angular-2-training-book.rangle.io/handout/di/angular2/inject_and_injectable.html

        2
  •  9
  •   eko    7 年前

    如果 MAT_DIALOG_DATA 是非工厂/类依赖项(如 string @Inject .

    同时检查 InjectionToken : https://angular.io/guide/dependency-injection#injectiontoken

    注射令牌


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

    如果您删除 @注入 在这种情况下,您将收到

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

        3
  •  9
  •   Yildiray Meric    7 年前

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

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

    同样在你的例子中,” @Inject “decorator与 InjectionToken

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

    要解决这个问题,您可以使用 Interfaces 这实际上是正确的解决方案,但由于JavaScript不支持您无法使用的接口 Interface 名称作为令牌,因为传输的代码不包含 界面 定义。

    因此,您需要使用 注射令牌 . 一 注射令牌 允许您将任何对象注入构造函数。您只需要在模块中声明它,并映射到要注入的真实类。通过这种方式,您可以为生产代码和测试代码使用不同的类。