2016-01-21 7 views
8

Ich habe eine Typoskriptklasse, die ein Modell darstellt, und ich möchte, dass Instanzen über den Service Http von angular mit einer API kommunizieren.Abhängigkeitsinjektion in Angular 2, wenn ein Konstruktor über Argumente verfügt

Der Konstruktor des Modells benötigt jedoch Argumente beim Erstellen von Instanzen. Zum Beispiel etwas super einfach:

class SomeModel{ 
    constructor(public id:number, public name:string,){ 
    } 

Ich mochte den Http Dienst injizieren, so dass es zu meinen Instanzen verfügbar ist, aber es scheint, wie der kanonische Weg, dies zu tun kommandiert den Konstruktor mit:

constructor(http:Http) 

Ich habe durch die Injector Dokumente gegraben, aber es ist ein wenig spärlich und ich habe nichts gefunden, was funktioniert. Gibt es eine Möglichkeit, einen Verweis auf einen Service wie Http aus dem DI-System zu erhalten, ohne das Konstruktormuster zu verwenden?

+0

Vielleicht könnten Sie 'provide' verwenden, wie wenn [Prüfung Http] (http://pastebin.com/UAJ3XeRf), aber es ist hässlich (; ich würde halte Modelle sauber und lasse die Komponenten Abrufen/Dienstleistungen ... – Sasxa

+0

Danke, ich weiß, dass @Sasxa.Die Anwendung ist eine Reihe von verschiedenen Arten von Knoten, die in einer Grafik-DB über eine API gespeichert werden.Jede Art von Knoten hat eine etwas andere Anforderung und funktioniert gut, um dies als Unterklassen einer abstrakten Knotenklasse zu modellieren. Um zu speichern, kann ich einfach 'nodeInstance.save()' sagen, anstatt eine Menge Logik in einem Service zu haben, um zu bestimmen, um was für einen Knoten es sich handelt und wie man es und seine Beziehungen speichert/abruft. Es ist möglich, dass es ein falscher Ansatz ist, aber es scheint mir nachhaltig, wenn ich einen schöneren Weg finden könnte, die Http-Referenz zu bekommen. –

+0

Ich habe durch Dokumente, insbesondere [http] (https://angular.io/docs/ts/latest/api/http/Http-class.html) und [xhrbackend] (https://angular.io /docs/ts/latest/api/http/XHRBackend-class.html), vielleicht [dies] (http://pastebin.com/bQcJALjA) wird für Sie arbeiten ... – Sasxa

Antwort

-5

Zunächst bezieht sich das Modell in angularJS auf $ scope oder in Angular 2 auf den Controller selbst. Sie sollten keine Klasse für das Modell erstellen und Logik darin einfügen müssen.

In einem Controller-Konstruktor können Sie mehrere Dienste über die Abhängigkeitsinjektion übergeben, indem Sie sie nur im Konstruktor angeben, der so viele Parameter benötigt, wie Sie benötigen.

constructor($scope:any, yourService:SomeService yourOtherService:OtherService) 
{ 

} 
+1

Diese Antwort ist ein wenig verwirrend - wo kommt $ scope in Angular2 ins Spiel? –

+0

Entschuldigung, ich bin es gewohnt, über Winkel in Bezug auf $ Scope nachzudenken. In 2.0 gibt es keinen $ scope. – Jim

2

Update

HTTP_PROVIDERS ist längst vorbei. HttpClientModule ist der aktuelle Ersatz.

original

Wenn Sie eine Klasse zu injizieren, die Konstruktorparameter die @Injectable Anmerkung hinzugefügt werden muss hat.

@Injectable() 
class SomeModel{ 
    // constructor(public id:number, public name:string,){ 
    // } 
    constructor(http:Http) {} 
} 

Für diese HTTP_PROVIDERS Bedürfnisse arbeiten auch

Angular2 beta - bootstrapping HTTP_PROVIDERS - "Unexpected Token <"

zu bootstrap(AppComponent, [HTTP_PROVIDERS]);

Siehe hinzugefügt werden, wenn Sie andere Argumente aus Ihrer Komponente übergeben müssen, so dass sie eine Funktion statt mit youcoud passieren.

Eine andere Möglichkeit besteht darin, die Instanz manuell zu erstellen und Http vom Injektor anzufordern.

+0

Danke @ Günter, ich glaube, Langley hat meine Antwort gefunden. Ich versuche, meine eigenen Argumente an meinen Konstruktor zu übergeben, während ich immer noch Zugriff auf den HTTP-Dienst innerhalb der SomeModel-Instanzen bekomme. –

+0

Ahh, habe nicht alle Kommentare gelesen, sah nur, dass es keine richtige Antwort gibt. –

+0

Warum nicht einfach eine Factory verwenden ('useFactory' anstelle von' useClass'), um die Abhängigkeit zu injizieren. Der Vorteil ist, dass Sie alle Ihre Anmerkungen löschen können. – Mik378

4

Ich schaffte es, das gleiche Problem mit Winkel 4 zu lösen. Zuerst erstellen Sie neue Injektor, die Komponente Injektor verwendet. Es weiß um Ihre SomeModel Klasse und übergibt modelParams als Instanz der SomeModelParameters Klasse. Dann verwenden Sie diesen neu erstellten Injektor, um eine Klasseninstanz zu erstellen.

@Injectable() 
class SomeModel { 
    constructor(http: Http, someModelParamters: SomeModelParameters) { } 
} 

export class MyComponent { 
    constructor(injector: Injector) { 
     const modelParams = new SomeModelParameters(); 
     const injectorWithModelParams = ReflectiveInjector.resolveAndCreate(
      [ 
       SomeModel, 
       { provide: SomeModelParameters, useValue: modelParams } 
      ], 
      injector); 
     this.someModel = injectorWithModelParams.resolveAndInstantiate([SomeModel]); 
    } 
} 
Verwandte Themen