Angularjs2 - 应用程序启动前的预加载服务器配置

时间:2016-08-19 07:53:53

标签: angular

我正在使用Angular2 RC5。我希望能够在我的应用程序启动之前加载我的服务器IP地址和一些其他配置参数。我怎样才能在最新的RC5中做到这一点?

我见过其他文章,但它们没有帮助:

  1. How to preload a config file in angular2:此处提供的答案特定于webpack。我正在使用systemjs。
  2. https://medium.com/@hasan.hameed/reading-configuration-files-in-angular-2-9d18b7a6aa4#.m8lontnas:这是针对Angular2的旧版本。使用的某些类已弃用。
  3. 非常感谢任何帮助。

    修改

    我尝试在app.module.ts中使用APP_INITIALIZER,如下所示:

        import { NgModule, provide, APP_INITIALIZER }       from "@angular/core";
        import { ConfigService } from "./shared/services/config.service";
        @NgModule({
            declarations: [AppComponent],
            imports: [BrowserModule,
                routes,
                FormsModule,
                HttpModule],
            providers: [AuthService,
                Title,
                appRoutingProviders,
                ConfigService],
            bootstrap: [AppComponent
                , provide(APP_INITIALIZER,
                    {
                        useFactory: (config: ConfigService) => () => config.load(),
                        deps: [ConfigService], multi: true
                    })]
        })
        export class AppModule { }
    

    这是我的config.service.ts文件:

        import { Config } from "../model/config";
    
        export class ConfigService {
            constructor() {
            }
    
            load(): Promise<Config> {
                let config: Config = new Config("localhost", "5050");
                return Promise.resolve(config);
            }
        }
    

    请注意,我最终会重新编写load以实际读取属性或某些此类文件以加载配置。

    这就是config.ts的样子:

    export class Config {
    
        constructor(
            private machine: string,
            private port: string
        ) {
        }
    
        private base_url: string = "http://" + this.machine +
        this.port + "/";
    
        public loginURL: string = this.base_url + "login";
    }
    

    我收到编译错误

    public/app/app.module.ts(27,11): error TS2345: Argument of type '{ declarations: (typeof AppComponent ...' is not assignable to parameter of type 'NgModuleMetadataType'.
      Types of property 'bootstrap' are incompatible.
        Type '(typeof AppComponent | Provider)[]' is not assignable to type '(Type | any[])[]'.
          Type 'typeof AppComponent | Provider' is not assignable to type 'Type | any[]'.
            Type 'Provider' is not assignable to type 'Type | any[]'.
              Type 'Provider' is not assignable to type 'any[]'.
                Property '[Symbol.iterator]' is missing in type 'Provider'.
    

    修改2

    我继续下一步。更新ConfigService以使用http.get读取json文件。现在我收到一个错误。以下是更新的文件:

    export class ConfigService {
        private config: Config;
            constructor(private http: Http) {
        }
    
        load(): Promise<Config> {
                this.http.get("/blah/config.json")
                     .map(res => res.json())
                     .subscribe((env_data) => {
                         console.log(env_data);
                      });
            this.config = new Config("localhost", "5050");
            return Promise.resolve(this.config);
        }
    
        getConfig(): Config {
            return this.config;
        }
    }
    

    这是NgModule类的提供程序部分

        providers: [AuthService,
        Title,
        appRoutingProviders,
        ConfigService,
        {
            provide: APP_INITIALIZER,
            useFactory: (config: ConfigService) => () => config.load(),
            deps: [ConfigService, Http],
            multi: true
        }],
    

    请注意,在RC6中,我无法导入HTTP_PROVIDERS,因为我得到的错误是这些错误不再在http模块中定义。这就是我尝试Http的原因。

    在运行时,我收到以下错误

    (index):27 Error: Error: Can't resolve all parameters for ConfigService: (?).(…)(anonymous function) @ (index):27
    ZoneDelegate.invoke @ zone.js:332
    Zone.run @ zone.js:225(anonymous function) @ zone.js:591
    ZoneDelegate.invokeTask @ zone.js:365
    Zone.runTask @ zone.js:265
    drainMicroTaskQueue @ zone.js:497
    ZoneTask.invoke @ zone.js:437
    

1 个答案:

答案 0 :(得分:26)

在根模块中提供

{provide: APP_INITIALIZER, useValue: () => promise, multi: true}]}

其中() => promise是一个调用,它返回一个解析为所需值的Promise。

另见How to pass parameters rendered from backend to angular2 bootstrap method

您可以将服务作为依赖项传递,您可以在其中存储结果。

<强>更新

export function loadConfig(config: ConfigService) => () => config.load()

@NgModule({
        declarations: [AppComponent],
        imports: [BrowserModule,
            routes,
            FormsModule,
            HttpModule],
        providers: [AuthService,
            Title,
            appRoutingProviders,
            ConfigService,
            { provide: APP_INITIALIZER,
              useFactory: loadConfig,
              deps: [ConfigService], 
              multi: true }
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule { }

更新2

Plunker example