2017-02-16 2 views
2

Je n'arrive pas à extraire les paramètres de configuration d'un fichier json avant le démarrage des composants de mon application. Pour ces composants, j'ai besoin des paramètres de configuration.Récupère les paramètres de configuration avant de démarrer les composants

Il n'y a aucun message d'erreur, mais le composant app.component.ts n'est pas initié. Quelque part l'exécution s'arrête. La lecture du json fonctionne bien.

functiontest.dev.config.json

{ 
    "name": "DE164813", 
    "node-uri": "http://localhost:4000" 
} 

Config.ts

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Http, Response } from '@angular/http'; 

@Injectable() 
export class Config { 

    private _env: Object 

    constructor(private http: Http) { 

    } 

    load() { 
     return new Promise((resolve, reject) => { 
      this.http.get('functiontest.dev.config.json') 
      .map(res => res.json()) 
      .subscribe((env_data) => { 
       this._env = env_data; 
       console.log("got env", this._env); 
      }) 
     }); 
    } 

    getEnv(key: any) { 
     return this._env[key]; 
    } 

}; 

app.module.ts

import { BrowserModule } from '@angular/platform-browser'; 
import { FormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http'; 
import { DatePickerModule } from 'ng2-datepicker'; 
import { Config } from './service/Config'; 
import { APP_INITIALIZER } from '@angular/core'; 
import { 
    NgModule, 
    ApplicationRef 
} from '@angular/core'; 
import { 
    removeNgStyles, 
    createNewHosts, 
    createInputTransfer 
} from '@angularclass/hmr'; 
import { 
    RouterModule, 
    PreloadAllModules 
} from '@angular/router'; 

/* 
* Platform and Environment providers/directives/pipes 
*/ 
import { ENV_PROVIDERS } from './environment'; 
import { ROUTES } from './app.routes'; 
// App is our top level component 
import { AppComponent } from './app.component'; 
import { APP_RESOLVER_PROVIDERS } from './app.resolver'; 
import { AppState, InternalStateType } from './app.service'; 
import { HomeComponent } from './home'; 
import { AboutComponent } from './about'; 
import { SensorTestComponent } from './sensortest'; 
import { TestReviewComponent } from './testreview'; 
import { NoContentComponent } from './no-content'; 
import { XLargeDirective } from './home/x-large'; 
import { ContractSelectComponent } from './contractselect/contractselect.component'; 

// Application wide providers 
const APP_PROVIDERS = [ 
    ...APP_RESOLVER_PROVIDERS, 
    AppState 
]; 

type StoreType = { 
    state: InternalStateType, 
    restoreInputValues:() => void, 
    disposeOldHosts:() => void 
}; 

function initConfig(config: Config){ 
    return() => config.load() 
} 

/** 
* `AppModule` is the main entry point into Angular2's bootstraping process 
*/ 
@NgModule({ 
    bootstrap: [ AppComponent ], 
    declarations: [ 
    AppComponent, 
    AboutComponent, 
    HomeComponent, 
    NoContentComponent, 
    XLargeDirective, 
    ContractSelectComponent, 
    SensorTestComponent, 
    TestReviewComponent 
    ], 
    imports: [ // import Angular's modules 
    BrowserModule, 
    FormsModule, 
    HttpModule, 
    DatePickerModule, 
    RouterModule.forRoot(ROUTES, { useHash: true, preloadingStrategy: PreloadAllModules }) 
    ], 
    providers: [ // expose our Services and Providers into Angular's dependency injection 
    ENV_PROVIDERS, 
    APP_PROVIDERS, 

    Config, 

    { 
     provide: APP_INITIALIZER, 
     useFactory: initConfig, 
     deps: [Config], 
     multi: true 
    } 

    ] 
}) 
export class AppModule { 

    constructor(
    public appRef: ApplicationRef, 
    public appState: AppState 

) { 

    } 

    public hmrOnInit(store: StoreType) { 
    if (!store || !store.state) { 
     return; 
    } 
    console.log('HMR store', JSON.stringify(store, null, 2)); 
    // set state 
    this.appState._state = store.state; 
    // set input values 
    if ('restoreInputValues' in store) { 
     let restoreInputValues = store.restoreInputValues; 
     setTimeout(restoreInputValues); 
    } 

    this.appRef.tick(); 
    delete store.state; 
    delete store.restoreInputValues; 
    } 

    public hmrOnDestroy(store: StoreType) { 
    const cmpLocation = this.appRef.components.map((cmp) => cmp.location.nativeElement); 
    // save state 
    const state = this.appState._state; 
    store.state = state; 
    // recreate root elements 
    store.disposeOldHosts = createNewHosts(cmpLocation); 
    // save input values 
    store.restoreInputValues = createInputTransfer(); 
    // remove styles 
    removeNgStyles(); 
    } 

    public hmrAfterDestroy(store: StoreType) { 
    // display new elements 
    store.disposeOldHosts(); 
    delete store.disposeOldHosts; 
    } 

} 

app.routes.ts

import { Routes, RouterModule } from '@angular/router'; 
import { HomeComponent } from './home'; 
import { ContractSelectComponent } from './contractselect/contractselect.component'; 
import { SensorTestComponent } from './sensortest'; 
import { TestReviewComponent } from './testreview'; 
import { AboutComponent } from './about'; 
import { NoContentComponent } from './no-content'; 

import { DataResolver } from './app.resolver'; 

export const ROUTES: Routes = [ 
    { path: '',  component: ContractSelectComponent }, 
    { path: 'sensortest/:orderId', component: SensorTestComponent }, 
    { path: 'testreview', component: TestReviewComponent }, 
    { path: '**', component: NoContentComponent }, 
]; 

contractselect.component.ts

import { Component } from '@angular/core'; 
import { OrderResource } from '../service/OrderResource'; 
import { ContractSelect } from './contractselect'; 
import { Order } from '../model/Order'; 
import { Router } from '@angular/router'; 
import { NodeResource } from '../service/NodeResource' 
import { NodeData } from '../model/NodeData'; 

@Component({ 
    selector: 'contractselect', 
    providers: [OrderResource, NodeResource], 
    templateUrl: 'contractselect.component.html' 
}) 
export class ContractSelectComponent { 

//... 

    constructor(private _orderResource: OrderResource, private _router:Router, private _nodeResource: NodeResource) { 
     this.orders = new Array<Order>(); 
     this.orderResource = _orderResource; 
     this.nodeResource = _nodeResource; 
     // set delay settings 
     this.delay = 1; 

     console.log("created ContractSelect Component"); 
    } 

// ... 
} 
+0

vous pouvez utiliser canactivate pour initialiser le service avec les paramètres get –

Répondre

0

Mon angulaire est un peu rouillé, mais je ne pense pas que juste parce que vous avez spécifié Config & config.load() en tant que dépendance à la structure angulaire DI, elle respectera en fait sa nature basée sur la promesse et retardera la construction des composants jusqu'à ce que la promesse soit résolue.


Quelqu'un avec une expérience plus anguleux peut probablement commenter plus et fournir une solution. Toutefois, il serait préférable que vous obteniez ces données de configuration d'une manière différente de l'application qu'un appel HTTP. La charge de l'application est probablement la suivante:

  • Le navigateur client envoie une requête HTTP à votre serveur et obtient une page Web + un gros paquet de JS, représentant l'application angulaire à une seule page.
  • Une seule page demande ensuite une autre requête HTTP au serveur pour obtenir la configuration.
  • L'application est initialisée en fonction de la configuration.

Vous avez une requête HTTP supplémentaire, ce qui ralentit la charge initiale, et ajoute toute cette complexité supplémentaire, et ne pas vraiment vous achetez que beaucoup.

Vous seriez mieux d'avoir ces données comme une constante dans votre code, peut-être avec des valeurs différentes pour différents environnements. Il est peu probable que vous le changiez souvent, et dans ce cas, le redéploiement de votre application sera probablement fait de toute façon. Selon la façon dont votre portion est faite, le serveur Web qui sert le javascript pourrait faire cuire les valeurs directement dans le JS, en fonction de sa configuration. Il est beaucoup plus facile de contrôler l'environnement et la configuration des composants côté serveur.