Ich habe eine Basis-App in Angular 2 erstellt, bin jedoch auf ein seltsames Problem gestoßen, bei dem ich keinen Dienst in eine meiner Komponenten einfügen kann. Es fügt sich jedoch gut in eine der drei anderen Komponenten ein, die ich erstellt habe.
Für den Anfang ist dies der 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;
}
}
Und die Komponente, mit der es nicht arbeiten will:
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);
}
}
Der Fehler, den ich in der Browserkonsole erhalte, ist folgender:
AUSNAHME: Es können nicht alle Parameter für HeaderComponent aufgelöst werden: (?).
Ich habe den Dienst in der Bootstrap-Funktion, also hat es einen Anbieter. Und ich scheine in der Lage zu sein, es ohne Probleme in den Konstruktor einer meiner anderen Komponenten zu injizieren.
angular
angular2-di
Keith Otto
quelle
quelle
'../'
einindex.ts
(Fass)? Können Sie versuchen, es aus der Datei zu importieren, in der es stattdessen direkt deklariert ist?Antworten:
Importieren Sie es aus der Datei, in der es direkt anstelle des Laufs deklariert ist.
Ich weiß nicht genau, was das Problem verursacht, aber ich habe es mehrmals erwähnt gesehen (wahrscheinlich eine Art zirkuläre Abhängigkeit).
Es sollte auch durch Ändern der Reihenfolge der Exporte im Fass behoben werden können (keine Details bekannt, wurde aber auch erwähnt)
quelle
2.0.2
). Ich finde Fässer immer noch nützlich, insbesondere wenn ich mehrere Modelle und Dienste zwischen verschiedenen Modulen importieren muss. Diesimport { cleanValues, getState, FirebaseService, NotificationService, ... } from '../../shared/services';
war ein Schmerz, als es nicht funktionierte (;NgModule
ist keine Hilfe bei Singleton-Diensten ...Zusätzlich zu den vorherigen Antworten scheint dieser Fehler auch ausgelöst zu werden, wenn Ihrem injizierbaren Service der eigentliche
@Injectable()
Dekorateur fehlt . Bevor Sie also die Sache mit der zyklischen Abhängigkeit und die Reihenfolge Ihrer Importe / Exporte debuggen, überprüfen Sie einfach, ob Ihr Service tatsächlich@Injectable()
definiert wurde.Dies gilt für das aktuelle Angular, Angular 2.1.0.
Ich habe eine Ausgabe zu diesem Thema eröffnet .
quelle
Router
von '@ angle / router' importieren. Ohne dieses Injectable tritt dieser Fehler immer auf (sobald Sie sich entscheiden, eine Zeile zu erstellen Code verwenden Sie diesen injizierten Router.@injectable()
ist nicht erforderlich. Welches ist eine weitere Kuriosität an sich. Für ein gutes Maß würde ich es trotzdem hinzufügen, einfach für den Fall, dass Sie sich jemals entscheiden sollten, etwas zu injizieren.Ab Angular
2.2.3
gibt es jetzt eineforwardRef()
Dienstprogrammfunktion, mit der Sie Anbieter einfügen können, die noch nicht definiert wurden.Mit nicht definiert meine ich, dass die Abhängigkeitsinjektionskarte den Bezeichner nicht kennt. Dies geschieht bei zirkulären Abhängigkeiten. Sie können zirkuläre Abhängigkeiten in Angular haben, die sehr schwer zu entwirren und zu sehen sind.
Durch Hinzufügen
@Inject(forwardRef(() => MobileService))
zum Parameter des Konstruktors im Quellcode der ursprünglichen Frage wird das Problem behoben.Verweise
Angular 2 Handbuch: ForwardRef
Vorwärtsreferenzen in Winkel 2
quelle
forwardRef()
war dort schon in alpha ;-) Es wird nur benötigt, wenn derMobile
Dienst weiter unten in derselben Datei deklariert ist. Wenn sich die Klassen in verschiedenen Dateien befinden, ist dies nicht erforderlichforwardRef()
forwardRef()
geholfen, dieCan't resolve all parameters for ...
Nachricht loszuwerden . Zumindest funktioniert die Komponente, während ich nach einer besseren Lösung für das Problem suche. (Und ja, die fehlerhafte Abhängigkeit wird direkt aus ihrer Datei importiert)forwardRef
. Es ist sehr schwer zu finden. Ich habe gestern den ganzen Tag gebraucht, um dieses Problem zu lösen.foreardRef
mich selbst zu benutzen, aber nicht mehr, nachdem sieNgModule
eingeführt wurden. Ich mache mir keine Sorgen, dass ich Wiederholungen verlieren könnte. Ich bin nur neugierig, warum Sie darauf stoßen, nachdem dies seit einigen Monaten nicht mehr aufgetaucht ist. Ich werde es mir genauer ansehen, wenn ich in ein paar Tagen wieder zu Hause bin. Vielen Dank für das Feedback.FALSCH # 1: Dekorateur vergessen:
FALSCH # 2: Auslassen des "@" Symbols:
FALSCH # 3: Auslassen von "()" Symbolen:
FALSCH # 4: Kleinbuchstaben "i":
FALSCH # 5: Sie haben vergessen: {Injectable} aus '@ angle / core' importieren;
RICHTIG:
quelle
Wie bereits erwähnt, wird das Problem durch die Exportbestellung innerhalb des Fasses verursacht, die durch zirkuläre Abhängigkeiten verursacht wird.
Eine ausführlichere Erklärung finden Sie hier: https://stackoverflow.com/a/37907696/893630
quelle
Ich bin auch darauf gestoßen, indem ich Service A in Service B eingefügt habe und umgekehrt.
Ich finde es gut, dass dies schnell fehlschlägt, da es wahrscheinlich sowieso vermieden werden sollte . Wenn Sie möchten, dass Ihre Dienste modularer und wiederverwendbarer sind, sollten Sie Zirkelverweise so weit wie möglich vermeiden. Dieser Beitrag hebt die Fallstricke hervor, die damit verbunden sind.
Daher habe ich folgende Empfehlungen:
EventService
) in Betracht ziehen, den beide Dienste einspeisen können, um Nachrichten auszutauschen.quelle
Zum Nutzen der Suchenden; Ich habe diesen Fehler bekommen. Es war einfach ein fehlendes @ -Symbol.
Dh dies erzeugt den
Can't resolve all parameters for MyHttpService
Fehler.Hinzufügen der fehlenden
@
Symbols behebt Problem.quelle
In meinem Fall musste ich
import "core-js/es7/reflect";
meiner Bewerbung etwas hinzufügen , damit es@Injectable
funktioniert.quelle
Eine andere Möglichkeit besteht
emitDecoratorMetadata
darin, in tsconfig.json nicht auf true gesetzt zu habenquelle
Sie erhalten diesen Fehler, wenn Sie Service A haben , der von einer statischen Eigenschaft / Methode von Service B abhängt, und der Service B selbst von Service A durch Abhängigkeitsinjektion abhängt. Es ist also eine Art zirkuläre Abhängigkeit, obwohl dies nicht der Fall ist, da die Eigenschaft / Methode statisch ist. Wahrscheinlich ein Fehler, der in Kombination mit AOT auftritt .
quelle
A -> B
und beide verwendeten dieselbe statische Klasse. Die LösungforwardRef
hilft, aber ich werde schauen, wie dies entwirrt werden könnte. Ich werde wahrscheinlich versuchen, aus dieser statischen Klasse einen echten Service zu machen (dies wird auch zu einem besseren Design führen).Neben dem fehlenden
@Injectable()
DekorateurFehlender
@Injectable()
Dekorator in der abstrakten Klasse hat Folgendes erzeugt: Kann nicht alle Parameter für den Service auflösen: (?) Der Dekorator muss sowohl inMyService
als auch in der abgeleiteten Klasse vorhanden seinBaseService
quelle
In meinem Fall ist es passiert, weil ich den Typ für einen Konstruktorparameter nicht deklariert habe.
Ich hatte so etwas:
und dann das Ändern in den Code unten löste mein Problem.
quelle
für mich fehlte es einfach
()
an @Injectable. Richtig ist @Injectable ()quelle
Das Entfernen von Parametern aus der injizierbaren Konstruktor () -Methode löste es für meinen Fall.
quelle
In meinem Fall war es wegen des Plugins Augury, deaktivieren Sie es wird gut funktionieren. Alternative Option ist aot, funktioniert auch.
Alle Credits an @ Boboss74, er hat die Antwort hier gepostet: https://github.com/angular/angular/issues/23958
quelle
Nun, für mich war das Problem noch ärgerlicher. Ich habe einen Dienst innerhalb eines Dienstes verwendet und vergessen, ihn als Abhängigkeit im AppModule hinzuzufügen! Ich hoffe, dies hilft jemandem, mehrere Stunden beim Ausfall der App zu sparen, nur um sie wieder aufzubauen
quelle
@Inject
Anmerkung. Ich habe genau übersehen, was die Fehlermeldung ein bisschen sagt. Wenn Sie keine zirkulären Abhängigkeiten vermuten, gehen Sie einfach zu der im Fehler genannten Klasse und sehen Sie sich alle Konstruktorparameter und alle mit Anmerkungen versehenen Klassenmitglieder an@Inject
und stellen Sie sicher, dass Sie DI für alle richtig ausführen. Mehr zu DI hier: angular.io/docs/ts/latest/guide/dependency-injection.htmlSie müssen ein Provider-Array in @Component Decorator oder in dem Modul hinzufügen, in dem Ihre Komponente deklariert ist. Innerhalb der Komponente können Sie wie folgt vorgehen:
quelle
In meinem Fall führt die Übergabe falscher Parameter an den Konstruktor zu diesem Fehler. Die Grundidee für diesen Fehler besteht darin, dass Sie unwissentlich einige falsche Argumente an eine Funktion übergeben haben.
Ich habe das gelöst, indem ich nur dieses Argument entfernt habe.
quelle
Ich habe diesen Fehler erhalten, als ich diesen Import in der Datei polyfills.ts versehentlich deaktiviert habe. Sie müssen sicherstellen, dass er importiert wird, um diesen Fehler zu vermeiden.
quelle
In meinem Fall habe ich versucht, "
NativeDateAdapter
" zu erweitern, um zu überschreiben "format(date: Date, displayFormat: Object)
Methode Methode .In AngularMaterial-2 DatePicker.
Im Grunde habe ich vergessen, eine
@Injectable
Anmerkung hinzuzufügen .Nachdem ich dies meiner "CustomDateAdapter" -Klasse hinzugefügt habe:
Fehler ist weg.
quelle
Diese Antwort kann für dieses Problem sehr hilfreich sein. Außerdem war für meinen Fall der Export des Dienstes
default
die Ursache.FALSCH:
RICHTIG:
quelle
Das Debuggen dieses Problems kann aufgrund des fehlenden Feedbacks im Fehler sehr schwierig sein. Wenn Sie sich Sorgen über eine tatsächliche zyklische Abhängigkeit machen, sollten Sie Folgendes im Stack-Trace beachten: a) den Namen des Dienstes b) den Konstruktorparameter in diesem Dienst, der ein Fragezeichen aufweist, z. B. wenn er so aussieht:
dann bedeutet dies, dass der 5. Parameter ein Dienst ist, der auch von AuthService abhängt. dh Fragezeichen bedeutet, dass es nicht von DI gelöst wurde.
Von dort müssen Sie nur noch die beiden Dienste entkoppeln, indem Sie den Code umstrukturieren.
quelle
Ich bin auf diesen Fehler gestoßen, indem ich den Namen des Dienstes falsch eingegeben habe , dh den Konstruktor (privater myService: MyService ).
Bei falsch geschriebenen Diensten konnte ich anhand der Seite in Chrome-> Konsole feststellen, welcher Dienst das Problem war (ich hatte mehrere im Konstruktor aufgelistet). Sie sehen als Teil der Nachricht eine "Parameter" -Arrayliste, indem Sie Objekt Objekt, Objekt Objekt ,? Anzeigen. (oder etwas ähnliches). Beachten Sie, wo das "?" ist und das ist die Position des Dienstes, der das Problem verursacht.
quelle
Obwohl die Bestellung der exportierten Klassen innerhalb von Fässern erwähnt wurde, kann das folgende Szenario den gleichen Effekt haben.
Angenommen , Sie haben Klassen
A
,B
undC
exportierte in derselben Datei , woA
hängt davon ab ,B
undC
:Da die abhängigen Klassen (dh in diesem Fall die Klassen
B
undC
) Angular noch nicht bekannt sind ( wahrscheinlich zur Laufzeit während des Angular-Abhängigkeitsinjektionsprozesses von der KlasseA
), wird der Fehler ausgelöst.Lösung
Die Lösung besteht darin, die abhängigen Klassen vor der Klasse zu deklarieren und zu exportieren, in der der DI ausgeführt wird.
dh im obigen Fall wird die Klasse
A
direkt nach der Definition ihrer Abhängigkeiten deklariert:quelle
In meinem Fall habe ich eine Klasse und eine Aufzählung aus derselben Komponentendatei exportiert:
mComponent.component.ts
::Dann habe ich versucht,
MyEnum
von einem Kind von zu verwendenMyComponentClass
. Dies verursachte den Fehler "Kann nicht alle Parameter beheben" .Durch das Verschieben
MyEnum
in einen separaten Ordner vonMyComponentClass
wurde mein Problem gelöst!Wie Günter Zöchbauer erwähnte, geschieht dies, weil ein Dienst oder eine Komponente zirkulär abhängig ist.
quelle
Wenn Ihr Dienst wird in der gleichen Datei als Bestandteil (das verbraucht es) und der Service definiert ist , definiert nach der Komponente in der Datei definiert ist, wird möglicherweise dieser Fehler angezeigt. Dies ist auf das gleiche 'forwardRef'-Problem zurückzuführen, das andere erwähnt haben. Derzeit ist VSCode nicht besonders gut darin, Ihnen diesen Fehler anzuzeigen, und der Build wird erfolgreich kompiliert.
Das Ausführen des Builds mit
--aot
kann dieses Problem aufgrund der Funktionsweise des Compilers maskieren (wahrscheinlich im Zusammenhang mit dem Schütteln von Bäumen).Lösung: Stellen Sie sicher, dass der Dienst in einer anderen Datei oder vor der Komponentendefinition definiert ist. (Ich bin nicht sicher, ob forwardRef in diesem Fall verwendet werden kann, aber es scheint ungeschickt, dies zu tun).
Wenn ich einen sehr einfachen Dienst habe, der sehr stark an eine Komponente gebunden ist (ähnlich wie ein Ansichtsmodell) - z.
ImageCarouselComponent
Ich kann esImageCarouselComponent.service.ts
so nennen, dass es nicht mit meinen anderen Diensten verwechselt wird.quelle
In meinem Fall war es ein Zirkelverweis. Ich hatte MyService, der Myservice2 anrief, und MyService2, der MyService anrief.
Nicht gut :(
quelle
In meinem Fall war der Grund der folgende:
Infolgedessen ist der Standardkonstruktor beim Versuch, ein Objekt A zu erstellen, fehlgeschlagen. Ich habe keine Ahnung, warum dies kein Kompilierungsfehler war.
Ich habe es behoben, indem ich einfach einen Konstruktor in A hinzugefügt habe, der den Konstruktor von B korrekt aufgerufen hat.
quelle
Erwischt!
Wenn Ihnen keine der oben genannten Antworten geholfen hat, importieren Sie möglicherweise ein Element aus derselben Datei, in die eine Komponente den Dienst einfügt.
Ich erkläre es besser:
Dies ist die Service - Datei :
Dies ist die Komponente Datei :
Es verursacht also Probleme, selbst wenn sich das Symbol nicht in derselben Komponente befindet, sondern nur in derselben Datei. Verschieben Sie das Symbol (es kann eine Funktion, eine Konstante, eine Klasse usw. sein) an eine andere Stelle, und der Fehler wird ausgeblendet
quelle
Versuchen Sie es mit Angular 6 und neueren Versionen
.. direkt über Ihrer Serviceklasse ohne andere Zeilen dazwischen
Vorteile
[ eckige Dokumente ]
quelle