web-dev-qa-db-fra.com

Angular 4: Quand et pourquoi @Inject est-il utilisé dans le constructeur?

Énoncé du problème

J'apprends Angular 4 et je suis tombé sur un code où @Inject est utilisé dans un constructor et je n'arrive pas à comprendre pourquoi ...

Code et source

J'utilise Angular 4 Material

Source du code:https://material.angular.io/components/dialog/overview

Dans le code, ils injectent MAT_DIALOG_DATA

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

Quelqu'un peut-il expliquer ce que cela signifie et quand/où devrions-nous le faire?

20
Vikas Bansal

@Inject() est un mécanisme manuel permettant à Angular de savoir qu'un Le paramètre doit être injecté.

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) { }
}

Dans ce qui précède, nous avons demandé que chatWidget soit le singleton Angular associé au class symbole ChatWidget en appelant @Inject(ChatWidget) . Il est important de noter que nous utilisons ChatWidget pour ses typages et comme référence à son singleton. Nous n'utilisons pas ChatWidget pour instancier quoi que ce soit, Angular le fait pour nous en coulisses

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

8
Rahul Singh

Si MAT_DIALOG_DATA est une dépendance non-usine/classe (comme string pour vos configurations), vous utilisez généralement @Inject.

Vérifiez également InjectionToken: https://angular.io/guide/dependency-injection#injectiontoken

Une solution pour choisir un jeton de fournisseur pour les dépendances non-classe consiste à définir et à utiliser un InjectionToken


Voici un plunker: http://plnkr.co/edit/GAsVdGfeRpASiBEy66Pu?p=preview

si vous supprimez @Inject dans ces cas, vous recevrez un

Impossible de résoudre tous les paramètres de ComponentName: (?)

7
eko

Conteneur IoC dans Angular utilise les déclarations de type dans le constructeur pour déterminer les objets à injecter dans les paramètres du constructeur.

Dans votre exemple, le paramètre "public data: any" N'a pas pu être déterminé par sa déclaration de type car il est défini comme "any". Pour résoudre ce problème, vous devez utiliser le décorateur "@Inject(MAT_DIALOG_DATA)" pour informer le conteneur IoC de l'objet qui doit être injecté dans le paramètre "data".

Dans votre exemple également, le décorateur "@Inject" Est utilisé avec un InjectionToken pour compliquer un peu les choses :)

Un InjectionToken est en fait une classe qui est utilisée pour nommer les objets à utiliser par le conteneur IoC pour injecter dans d'autres classes. Normalement, vous pouvez utiliser n'importe quel nom de classe comme jeton pour l'injection IoC (comme "MatDialogRef<DialogOverviewExampleDialog>" Dans votre exemple) et cela fonctionne très bien. Mais lorsque vous commencez à écrire vos UnitTests, vous vous rendez compte que vous devez utiliser des objets Mock au lieu d'objets réels à injecter dans vos classes et lorsque vous utilisez de vrais noms de classe comme jetons, vous ne pouvez pas le faire.

Pour résoudre ce problème, vous pouvez utiliser Interfaces comme noms de jeton et c'est en fait la bonne solution, mais comme JavaScript ne prend pas en charge les interfaces, vous ne pouvez pas utiliser Interface noms comme jetons, car le code transpilé ne contiennent Interface définitions.

À la suite de tout cela, vous devez utiliser InjectionToken. Un InjectionToken vous permet d'injecter n'importe quel objet dans votre constructeur. Il vous suffit de le déclarer dans vos modules et de le mapper sur la classe réelle que vous souhaitez injecter. De cette façon, vous pouvez utiliser différentes classes pour vos codes de production et de test.

3
Yildiray Meric