2015-12-17 6 views
9

Ich erhalte diesen Fehler beim Versuch, den Http Service in meine PanelsService zu injizieren.Injection error: Kann nicht alle Parameter auflösen

import {Component} from 'angular2/core'; 
import {Http} from 'angular2/http'; 

export class PanelsService { 

    constructor(public http:Http) { } 

    getPanelFilters() { 
    var url = '../../data/panelFilters/' + 13677 + '.json' 

    return this.http.get(url) 
    } 

} 

Ich bin versucht, die PanelsService von meinem SidebarComponent zuzugreifen:

import {PanelsService} from '../panels/panels.service'; 

@Component({ 
    .... 
    providers: [PanelsService] 
}) 

export class SidebarComponent implements OnInit { 

    constructor(public panelsService:PanelsService) { } 

    ngOnInit() { 
    console.log('I am the sidebar component'); 
    } 

} 

Es sollte beachtet werden, dass meine tsconfig.json auch die Linien hat:

"emitDecoratorMetadata": true, 
"experimentalDecorators": true, 

Ich habe versucht, mit @Injectable wie gezeigt here aber wenn ich meine Klasse mit @Injectable() schmücken, bekomme ich einen Fehler in den Cons ole:

enter image description here

boot.js einfach meine app Komponente Schopf aus dem Sumpf, es injiziert keine Abhängigkeiten:

import {bootstrap} from 'angular2/platform/browser'; 
import {AppComponent} from './components/app.component'; 

bootstrap(AppComponent).catch(err => console.error(err)); 

Jede Hilfe würde geschätzt.

+1

Sie müssen das HTTP-Paket in Ihre Skript-Tags einschließen. –

+0

@EricMartinez Genau das ist realisiert - danke – garethdn

Antwort

24

In Ihrem Code fehlt eine Sache: Provider.

Mit

export class PanelsService { 

    constructor(public http:Http) { } 
} 

Sie bitten um eine Abhängigkeit, die der Injektor mit dem Token Http (Typ Anmerkung) identifiziert. Allerdings gibt es nichts in Ihrem Code (mindestens wie hier gezeigt), der Ihrem Injektor was es für das Token Http zurückgibt. Es ist also nur die Hälfte der Informationen.

Um eine Abhängigkeit aufzulösen, brauchen wir ein Token (das, wonach wir suchen) und einen Provider (die Sache, die das Objekt erzeugt, nach dem wir fragen). Der Provider kann entweder unter bootstrap() oder auf Komponentenebene unter Verwendung der providers Eigenschaft im @Component() Decorator konfiguriert werden.

Wenn Sie nicht jedes Mal eine neue Instanz von Http erstellen möchten, ist es am sinnvollsten, diesen Provider unter bootstrap() so zu konfigurieren, dass dieselbe Instanz in Ihrer gesamten Anwendung verfügbar ist.

Hier ist, was ein Anbieter für Http aussehen könnte:

import {provide} from 'angular2/core'; 
import {bootstrap} from 'angular2/platform/browser'; 
import {Http} from 'angular2/http'; 

bootstrap(YourApp, [ 
    provide(Http, {useClass: Http}) 
]); 

provide() ein Token Http nimmt und einen Anbieter mit einem Rezept konfiguriert, das beschreibt, wie ein Objekt von etwas (useClass: Http) erstellen. Wenn das Rezept useClass und die Klasse ist das gleiche wie das Token, können wir die folgende Kurzschreibweise Syntax:

bootstrap(YourApp, [ 
    Http 
]); 

aber wir erkennen, dass dies nicht genug ist, da es sich herausstellt, dass Http DI verwendet selbst für seine eigenen Abhängigkeiten auch. Das heißt, wir brauchen auch Provider für diese Abhängigkeiten. Glücklicherweise bietet Angular für diese Fälle bereits eine vordefinierte Liste von Anbietern an.

HTTP_PROVIDERS ist eine Sammlung von Provider-Konfigurationen, die benötigt werden, um Http funktionieren zu lassen. Also alles, was Sie tun müssen, ist:

import {HTTP_PROVIDERS} from 'angular2/http'; 

bootstrap(YourApp, [HTTP_PROVIDERS]); 

Jetzt ist Ihre App kennt alle Abhängigkeiten, Tokens und Anbieter für alles Http.

Sie können eine ausführlichere Erklärung in diesem article finden.

+1

Das ist eine tolle Antwort, danke. Ich hatte diesen Artikel und ein paar andere über Thoughtgram gelesen, war aber ziemlich verwirrt und unsicher, ob ich "resolveAndCreate" überall verwenden sollte. Deine Erklärung war viel klarer. – garethdn

+1

Beachten Sie, dass die 'provide' -Funktion veraltet ist; akzeptiert nun ein Objekt mit einer 'provide' ** Eigenschaft ** und einer' useClass' Eigenschaft [wie hier beschrieben] (http://stackoverflow.com/a/38341311/1175496) –