2016-06-30 2 views
2

Ich habe dieses Szenario.Angular 2 - Dienste, die andere Dienste verbrauchen, bevor eine Methode aufgerufen wird

backend.json

{ 
"devServer": "http://server1/'", 
"proServer" : "http://server2/'", 
"use" : "devServer" 
} 

global.service.ts

import {Injectable} from '@angular/core'; 
import {Http, HTTP_PROVIDERS, Response, RequestOptions, URLSearchParams} from '@angular/http'; 
@Injectable() 
export class GlobalService { 
constructor(private _http: Http){} 
getBackendServer(){ 
    return this.server = this._http.get('./backend.json') 
     .map((res:Response) => res.json()) 
} 
} 

Und ich habe diesen anderen Service: search.service.ts

import {Injectable} from '@angular/core'; 
import {Http, HTTP_PROVIDERS, Response, RequestOptions, URLSearchParams} from '@angular/http'; 
import {GlobalService} from '../services/global.service'; 
import 'rxjs/add/operator/map'; 
@Injectable() 
export class SearchService { 
server; 
constructor(private _http: Http, private gs: GlobalService) { 
    this.server = gs.getBackendServer().subscribe(
     (data) => { 
      this.server = data[data.use]; 
     }, 
     (err) => { 
      console.log(err); 
     } 
    ); 
} 
DoGeneralSearch(params:Search){ 
    console.log(this.server); 
    let options = this.buildOptions(params); 
    return this._http.get(this.server + 'room/search', options) 
    .map((res:Response) => res.json()) 
} 
} 

Was ich will do: Sieht offensichtlich aus: Ich möchte die Informationen zur URL des Backend-Servers in einer JSON-Datei behalten - und den globalen Dienst zurückgeben Auf dem Server kann dies in jeder Methode des Suchdienstes verwendet werden.

Das Problem ist: Die DoGeneralSearch() -Methode wird ausgeführt, bevor der globale Dienst die Aufgabe auflösen kann, um die JSON-Datei zu lesen und das Ergebnis zurückzugeben. Also, ich habe einen this.server = Subscriber {isUnsubscribed: false, syncErrorValue: null, syncErrorThrown: false, syncErrorThrowable: false, isStopped: false ...} und stattdessen das Ergebnis selbst.

Ich muss herausfinden, wie man verhindert, dass die Methode DoGeneralSearch ausgeführt wird, nachdem die Variable this.server aufgelöst wurde.

Irgendwelche Vorschläge?

Antwort

7

Ich denke, dass Sie solche Hinweise beim Start der Anwendung laden können. Hierfür könnten Sie den Dienst APP_INITIALIZER nutzen. Die Anwendung wartet darauf, dass das zurückgegebene Versprechen vor dem tatsächlichen Start aufgelöst wird. Hier

ist ein Beispiel:

provide(APP_INITIALIZER, { 
    useFactory: (service:GlobalService) =>() => service.load(), 
    deps:[GlobalService, HTTP_PROVIDERS], multi: true 
}) 

Die load Methode so etwas möchte:

load():Promise<Site> { 
    var promise = this.http.get('config.json').map(res => res.json()).toPromise(); 
    promise.then(config => this.devServer = config.devServer); 
    return promise; 
} 

Dann können Sie direkt die devServer (synchron) verwenden ...

See Dieses Problem auf GitHub für weitere Details:

+1

Excellent Hinweis auf 'APP_INITIALIZER'! Schließlich hat die Frage "Wie man die App vor der Initialisierung pausiert" von AngularJS-Tagen eine faire Antwort erhalten. – estus

+0

Hallo, ich habe diesen Ansatz gemacht, aber wenn ich das Versprechen 'service.load()' vom 'APP_INITIALIZER' Provider debugge, gibt es immer undefined zurück. Ich habe überprüft, dass die "load" -Methode einen Wert im "GlobalService" zurückgibt, aber dieses Modul scheint am Ende des Anwendungsladeprozesses geladen zu sein. – snaphuman

+0

Mit [@nglibs \ config] (https://github.com/nglibs/config) in Ihrem Projekt, das Ihnen die erforderlichen Konfigurationsdaten von backend.json zur Verfügung stellt, die während der Initialisierung der Anwendung gelöst wurden –