2017-02-16 49 views
2

我的應用程序組件啓動之前,我的配置參數超出了json文件的問題。對於這些組件,我需要配置參數。在啓動組件之前獲取配置參數

沒有錯誤消息,但app.component.ts未啓動。執行停止的地方。閱讀json工作正常。

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

你可以使用canactivate來初始化帶get參數的服務 –

回答

0

我的角度是有點生疏,但我不認爲僅僅因爲您指定Config & config.load()作爲對角度DI框架的依賴,它將實際上尊重它的基於承諾的性質,並在Promise解決之前延遲組件的構建。


有人用更加棱角分明經驗也許可以多加評論提供解決方案。

但是,最好以與HTTP應用程序不同的方式獲取配置數據。最有可能的應用程序負載是這樣的:

  • 客戶端瀏覽器發出HTTP請求到服務器,並得到一個網頁+ JS的一大捆,代表單頁角的應用程序。
  • 單頁應用程序然後向服務器發出另一個HTTP請求以獲取配置。
  • 應用程序根據配置進行初始化。

你有一個額外的HTTP請求,並會減慢初始負荷,並增加這些額外的複雜性,並沒有真正給你買多。

您最好將代碼中的數據作爲常量使用,也許對於不同的環境使用不同的值。你不太可能經常改變它,在這種情況下,重新部署你的應用程序很可能會被完成。取決於你的服務如何完成,服務於JavaScript的Web服務器可以直接將值燒入JS,具體取決於它的配置。控制服務器端組件的環境和配置要容易得多。