J'ai créé une application de base dans Angular 2, mais j'ai rencontré un problème étrange où je ne peux pas injecter de service dans l'un de mes composants. Cependant, il injecte bien dans l'un des trois autres composants que j'ai créés.
Pour commencer, voici le service:
import { Injectable } from '@angular/core';
@Injectable()
export class MobileService {
screenWidth: number;
screenHeight: number;
constructor() {
this.screenWidth = window.outerWidth;
this.screenHeight = window.outerHeight;
window.addEventListener("resize", this.onWindowResize.bind(this) )
}
onWindowResize(ev: Event) {
var win = (ev.currentTarget as Window);
this.screenWidth = win.outerWidth;
this.screenHeight = win.outerHeight;
}
}
Et le composant avec lequel il refuse de travailler:
import { Component, } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';
import {MobileService} from '../';
@Component({
moduleId: module.id,
selector: 'pm-header',
templateUrl: 'header.component.html',
styleUrls: ['header.component.css'],
directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
mobileNav: boolean = false;
constructor(public ms: MobileService) {
console.log(ms);
}
}
L'erreur que j'obtiens dans la console du navigateur est la suivante:
EXCEPTION: impossible de résoudre tous les paramètres de HeaderComponent: (?).
J'ai le service dans la fonction bootstrap donc il a un fournisseur. Et je semble pouvoir l'injecter dans le constructeur de n'importe lequel de mes autres composants sans problème.
angular
angular2-di
Keith Otto
la source
la source
'../'
unindex.ts
(baril)? Pouvez-vous essayer de l'importer à partir du fichier où il est déclaré directement à la place?Réponses:
Importez-le du fichier où il est déclaré directement au lieu du baril.
Je ne sais pas ce qui cause exactement le problème mais je l'ai vu mentionné plusieurs fois (probablement une sorte de dépendance circulaire).
Il devrait également être réparable en modifiant l'ordre des exportations dans le baril (je ne sais pas les détails, mais a également été mentionné)
la source
2.0.2
). Je trouve les barils toujours utiles, surtout lorsque j'ai besoin d'importer plusieurs modèles et services entre différents modules. Ceimport { cleanValues, getState, FirebaseService, NotificationService, ... } from '../../shared/services';
fut une douleur quand cela n'a pas fonctionné (;NgModule
n'aide pas avec les services singleton ...En plus des réponses précédentes données, il semble que cette erreur soit également lancée lorsque votre service injectable manque le
@Injectable()
décorateur réel . Donc, avant de déboguer la dépendance cyclique et l'ordre de vos importations / exportations, vérifiez simplement si votre service a réellement@Injectable()
défini.Cela s'applique à la dernière version angulaire actuelle, Angular 2.1.0.
J'ai ouvert un dossier à ce sujet .
la source
Router
depuis '@ angular / router' et sans cet injectable, cette erreur se produira toujours (dès que vous décidez de créer une ligne de utiliser le code du routeur injecté.@injectable()
n'est pas requise. Ce qui est une autre bizarrerie sur lui-même. Pour faire bonne mesure, je l'ajouterais quand même, simplement pour quand vous devriez décider d'injecter quelque chose.Depuis Angular,
2.2.3
il existe désormais uneforwardRef()
fonction utilitaire qui vous permet d'injecter des fournisseurs qui n'ont pas encore été définis.Par non défini, je veux dire que la carte d'injection de dépendances ne connaît pas l'identifiant. C'est ce qui se passe lors des dépendances circulaires. Vous pouvez avoir des dépendances circulaires dans Angular qui sont très difficiles à démêler et à voir.
L'ajout
@Inject(forwardRef(() => MobileService))
au paramètre du constructeur dans le code source de la question d'origine résoudra le problème.Références
Manuel Angular 2: ForwardRef
Références directes dans Angular 2
la source
forwardRef()
était déjà là en alpha ;-) Il n'est nécessaire que si leMobile
service est déclaré plus bas dans le même fichier. Si les classes sont dans des fichiers différents, il n'est pas nécessaire deforwardRef()
forwardRef()
cela a aidé à se débarrasser duCan't resolve all parameters for ...
message. Au moins, le composant fonctionne pendant que je cherche une meilleure solution au problème. (Et oui, la dépendance défaillante est importée directement de son fichier)forwardRef
. C'est très difficile à trouver. Hier, il m'a fallu toute la journée pour résoudre ce problème.foreardRef
moi-même mais pas plus après l'NgModule
introduction. Je ne suis pas inquiet de perdre des représentants. Je suis juste curieux de savoir pourquoi vous rencontrez cela après que cela ne soit plus apparu depuis quelques mois. J'y regarderai de plus près quand je serai de retour dans quelques jours. Merci beaucoup pour la rétroaction.FAUX # 1: Oubliant le décorateur:
FAUX # 2: Omission du symbole "@":
FAUX # 3: Omettre les symboles "()":
FAUX # 4: "i" minuscule:
FAUX # 5: Vous avez oublié: importez {Injectable} de '@ angular / core';
CORRECT:
la source
Comme déjà indiqué, le problème est dû à la commande d'exportation dans le baril qui est causée par des dépendances circulaires.
Une explication plus détaillée est ici: https://stackoverflow.com/a/37907696/893630
la source
J'ai également rencontré cela en injectant le service A dans le service B et vice versa.
Je pense que c'est une bonne chose que cela échoue rapidement car il devrait probablement être évité de toute façon . Si vous souhaitez que vos services soient plus modulaires et réutilisables, il est préférable d'éviter autant que possible les références circulaires. Ce post met en évidence les pièges qui l'entourent.
Par conséquent, j'ai les recommandations suivantes:
EventService
) que les deux services peuvent injecter afin d'échanger des messages.la source
Pour le bénéfice des chercheurs; J'ai eu cette erreur. C'était simplement un symbole @ manquant.
C'est à dire cela produit l'
Can't resolve all parameters for MyHttpService
erreur.L'ajout du
@
symbole manquant le corrige.la source
Dans mon cas, je devais ajouter
import "core-js/es7/reflect";
à ma demande pour faire du@Injectable
travail.la source
Une autre possibilité est de ne pas avoir
emitDecoratorMetadata
défini la valeur true dans tsconfig.jsonla source
Vous obtenez cette erreur si vous disposez du service A qui dépend d'une propriété / méthode statique du service B et que le service B lui-même dépend de l' injection de dépendances par le service A. C'est donc une sorte de dépendance circulaire, même si ce n'est pas le cas puisque la propriété / méthode est statique. Probablement un bogue qui se produit en combinaison avec AOT .
la source
A -> B
et les deux utilisaient la même classe statique. La solution avecforwardRef
aide, mais je vais voir comment cela pourrait être démêlé. J'essaierai probablement de faire un vrai service à partir de cette classe statique (cela conduira également à une meilleure conception).En plus du
@Injectable()
décorateur manquantLe
@Injectable()
décorateur manquant dans la classe abstraite a produit Impossible de résoudre tous les paramètres de service: (?) Le décorateur doit être présentMyService
dans la classe dérivéeBaseService
la source
Dans mon cas, cela s'est produit parce que je n'ai pas déclaré le type d'un paramètre constructeur.
J'avais quelque chose comme ça:
puis le changer pour le code ci-dessous a résolu mon problème.
la source
pour moi, c'était juste un manque de
()
@Injectable. Le bon est @Injectable ()la source
La suppression des paramètres de la méthode constructor () injectable l'a résolu pour mon cas.
la source
Dans mon cas, c'était à cause du plugin Augury, désactivez-le, cela fonctionnera bien. L'option alternative est aot, fonctionne également.
tous les crédits à @ Boboss74, il a posté la réponse ici: https://github.com/angular/angular/issues/23958
la source
Eh bien, pour moi, le problème était encore plus ennuyeux, j'utilisais un service au sein d'un service et j'ai oublié de l'ajouter comme dépendance dans l'appModule! J'espère que cela permet à quelqu'un d'économiser plusieurs heures en cassant l'application uniquement pour la reconstituer
la source
@Inject
annotation. J'écartais exactement ce que dit le message d'erreur. Si vous ne soupçonnez pas de dépendances circulaires, accédez simplement à la classe mentionnée dans l'erreur et examinez tous les paramètres du constructeur et tous les membres de classe annotés@Inject
et assurez-vous que vous faites bien DI sur chacun d'eux. Plus d'informations sur DI ici: angular.io/docs/ts/latest/guide/dependency-injection.htmlVous devez ajouter un tableau de fournisseurs dans le décorateur @Component ou dans le module où votre composant est déclaré. Composant intérieur, vous pouvez faire comme ci-dessous:
la source
Dans mon cas, le passage de paramètres incorrects au constructeur génère cette erreur, l'idée de base à propos de cette erreur est que vous avez inconsciemment transmis des arguments incorrects à une fonction.
J'ai résolu cela en supprimant simplement cet argument.
la source
Pour moi, j'ai eu cette erreur lorsque j'ai désactivé par erreur cette importation dans le fichier polyfills.ts, vous devez vous assurer qu'elle est importée pour éviter cette erreur.
la source
Dans mon cas, j'essayais d'étendre la méthode "
NativeDateAdapter
" afin de remplacer laformat(date: Date, displayFormat: Object)
méthode " ".Dans AngularMaterial-2 DatePicker.
Donc, fondamentalement, j'ai oublié d'ajouter une
@Injectable
annotation.Après avoir ajouté ceci à ma classe "CustomDateAdapter":
L'erreur a disparu.
la source
Cette réponse peut être très utile pour ce problème. De plus, pour mon cas, exporter le service comme en
default
était la cause.FAUX:
CORRECT:
la source
Cela peut être un problème très difficile à déboguer en raison du manque de rétroaction dans l'erreur. Si vous êtes préoccupé par une dépendance cyclique réelle, voici la chose la plus importante à regarder dans la trace de la pile a) le nom du service b) le paramètre constructeur dans ce service qui a un point d'interrogation, par exemple s'il ressemble à ceci:
cela signifie alors que le 5ème paramètre est un service qui dépend également d'AuthService. c.-à-d. point d'interrogation, signifie qu'il n'a pas été résolu par DI.
De là, il vous suffit de découpler les 2 services en restructurant le code.
la source
J'ai rencontré cette erreur en tapant mal le nom du service, c'est-à-dire le constructeur ( myService privé : MyService ).
Pour les services mal orthographiés, j'ai pu déterminer quel service était le problème (j'en avais plusieurs répertoriés dans le constructeur) en inspectant la page dans Chrome-> Console. Vous verrez dans le message une liste de tableaux "paramètres" en affichant l'objet Object, object Object,? (ou quelque chose comme ça). Remarquez où le "?" est et c'est la position du service qui cause le problème.
la source
Bien que l' ordre des classes exportées à l'intérieur des barils ait été mentionné, le scénario suivant peut également produire le même effet.
Supposons que vous ayez des classes
A
,B
etC
exportées à partir du même fichier où celaA
dépendB
etC
:Étant donné que les classes dépendantes (c'est-à-dire dans ce cas les classes
B
etC
) ne sont pas encore connues d'Angular, ( probablement au moment de l'exécution pendant le processus d'injection de dépendance d'Angular sur la classeA
), l'erreur est déclenchée.Solution
La solution consiste à déclarer et exporter les classes dépendantes avant la classe où l'ID est effectuée.
c'est-à-dire que dans le cas ci-dessus, la classe
A
est déclarée juste après la définition de ses dépendances:la source
Dans mon cas, j'exportais une classe et une énumération à partir du même fichier de composant:
mComponent.component.ts
:Ensuite, j'essayais d'utiliser
MyEnum
d'un enfant deMyComponentClass
. Cela provoquait l' erreur Impossible de résoudre tous les paramètres .En déplaçant
MyEnum
dans un dossier séparé deMyComponentClass
, cela a résolu mon problème!Comme Günter Zöchbauer l'a mentionné, cela se produit car un service ou un composant dépend de façon circulaire.
la source
Si votre service est défini dans le même fichier qu'un composant (qui le consomme) et que le service est défini après le composant dans le fichier, vous pouvez obtenir cette erreur. Cela est dû au même problème «forwardRef» que d'autres ont mentionné. Pour le moment, VSCode n'est pas très utile pour vous montrer cette erreur et la compilation se compile avec succès.
L'exécution de la build avec
--aot
peut masquer ce problème en raison de la façon dont le compilateur fonctionne (probablement lié au tremblement de l'arbre).Solution: assurez-vous que le service est défini dans un autre fichier ou avant la définition du composant. (Je ne sais pas si forwardRef peut être utilisé dans ce cas, mais cela semble maladroit de le faire).
Si j'ai un service très simple qui est très fortement lié à un composant (un peu comme un modèle de vue) - par exemple.
ImageCarouselComponent
, Je peux le nommerImageCarouselComponent.service.ts
afin qu'il ne soit pas mélangé avec mes autres services.la source
Dans mon cas, c'était une référence circulaire. J'ai eu MyService appelant Myservice2 et MyService2 appelant MyService.
Pas bon :(
la source
Dans mon cas, la raison était la suivante:
Par conséquent, lors de la tentative de création d'un objet A, le constructeur par défaut a échoué. Je n'ai aucune idée pourquoi ce n'était pas une erreur de compilation.
Je l'ai corrigé en ajoutant simplement un constructeur dans A, qui a correctement appelé le constructeur de B.
la source
Je t'ai eu!
Si aucune des réponses ci-dessus ne vous a aidé, vous importez peut-être un élément du même fichier où un composant injecte le service.
J'explique mieux:
Voici le fichier de service :
Voici le fichier composant :
Cela pose donc des problèmes même si le symbole n'est pas à l'intérieur du même composant, mais juste à l'intérieur du même fichier. Déplacez le symbole (il peut s'agir d'une fonction, d'une constante, d'une classe, etc.) ailleurs et l'erreur disparaîtra
la source
pour les versions angulaires 6 et plus récentes, essayez
.. juste au-dessus de votre classe de service sans autre ligne entre les deux
avantages
[ documents angulaires ]
la source