2017-04-26 112 views
12

打字稿:2.2.0 角:4.0Angular4 APP_INITIALIZER不會耽誤初始化

我試圖以確保ConfigService對象是通過使用APP_INITIALIZER之前應用程序啓動初始化。我發現了很多如何做到這一點的例子,但是它們中的任何一個都似乎延遲了應用程序的初始化。這裏只是我試圖實現的一些例子。

https://github.com/angular/angular/issues/9047 https://gist.github.com/fernandohu/122e88c3bcd210bbe41c608c36306db9 Angular2 APP_INITIALIZER not consistent

這裏是我NgModule

export function init(config: ConfigService) { 
    return() => { 
    config.load(); 
    }; 
} 


@NgModule({ 
    declarations: [ 
    AppComponent 
    ], 
    imports: [ 
    BrowserModule, 
    FormsModule, 
    HttpModule, 
    AppRoutingModule 
    ], 
    providers: [ 
    { 
     'provide': APP_INITIALIZER, 
     'useFactory': init, 
     'deps': [ConfigService], 
     'multi': true 
    }, 
    ConfigService 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 

這裏是ConfigService

@Injectable() 
export class ConfigService { 
    private config: ApplicationConfiguration; 

    get apiRoot() { 
    return this.getProperty('apiRoot'); // <--- THIS GETS CALLED FIRST 
    } 

    constructor(private http: Http) { 
    } 

    load(): Promise<any> { 
     console.log('get user called'); 
     const promise = this.http.get('./../../assets/config.json').map((res) => res.json()).toPromise(); 
     promise.then(config => { 
     this.config = config;  // <--- THIS RESOLVES AFTER 
     console.log(this.config); 
     }); 
    return promise; 
    } 

    private getProperty(property: string): any { 
    //noinspection TsLint 
    if (!this.config) { 
     throw new Error(`Attempted to access configuration property before configuration data was loaded, please double check that 'APP_INITIALIZER is properly implemented.`); 
    } 

    if (!this.config[property]) { 
     throw new Error(`Required property ${property} was not defined within the configuration object. Please double check the 
     assets/config.json file`); 
    } 

    return this.config[property]; 
    } 
} 

,並測試一切我已經注射ConfigService我nto AppComponent與此。

import { Component } from '@angular/core'; 
import {ConfigService} from './services/config.service'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.scss'] 
}) 
export class AppComponent { 
    title = 'app works!'; 
    fullImagePath = '/src/image/avatar.jpeg'; 


    constructor(private config: ConfigService) { 
    config.apiRoot; 
    } 
} 

回答

12

看起來你忘了從工廠返回值:

export function init(config: ConfigService) { 
    return() => { 
    return config.load(); // add return 
    }; 
} 

或相同的代碼可以有點不久寫的:

export function init(config: ConfigService) { 
    return() => config.load(); 
} 
+1

是的,這就是它了!非常感謝! – DynaWeb

+0

對於閱讀此內容的其他人,這些內容也是最近的(截至目前)https://juristr.com/blog/2018/01/ng-app-runtime-config/#runtime-configuration – redfox05