2017-02-16 1 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, может выпекать значения прямо в JS, в зависимости от его конфигурации. Гораздо проще управлять средой и конфигурацией серверных компонентов.

Смежные вопросы