更新2
Plunker 示例
更新AoT
为了与 AoT 合作,工厂关闭需要移出
function loadContext(context: ContextService) {
return () => context.load();
}
@NgModule({
...
providers: [ ..., ContextService, { provide: APP_INITIALIZER, useFactory: loadContext, deps: [ContextService], multi: true } ],
另见https://github.com/angular/angular/issues/11262
更新RC.6 和 2.0.0 最终示例
function configServiceFactory (config: ConfigService) {
return () => config.load();
}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule,
routes,
FormsModule,
HttpModule],
providers: [AuthService,
Title,
appRoutingProviders,
ConfigService,
{ provide: APP_INITIALIZER,
useFactory: configServiceFactory
deps: [ConfigService],
multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
如果不需要等待初始化完成,也可以使用`class AppModule {}的构造函数:
class AppModule {
constructor(/*inject required dependencies */) {...}
}
提示(循环依赖)
例如,注入路由器会导致循环依赖。要解决此问题,请注入Injector
并获取依赖项
this.myDep = injector.get(MyDependency);
而不是MyDependency
直接注入,如:
@Injectable()
export class ConfigService {
private router:Router;
constructor(/*private router:Router*/ injector:Injector) {
setTimeout(() => this.router = injector.get(Router));
}
}
更新
这应该在 RC.5 中工作相同,但将提供者添加到providers: [...]
根module而不是bootstrap(...)
(尚未测试自己)。
更新
这里解释了一种完全在 Angular 内部完成的有趣方法https://github.com/angular/angular/issues/9047#issuecomment-224075188
您可以使用APP_INITIALIZER
which 将在应用程序初始化时执行函数,并在函数返回Promise时延迟它提供的内容。这意味着应用程序可以在没有太多延迟的情况下进行初始化,您还可以使用现有的服务和框架功能。
例如,假设您有一个多租户解决方案,其中站点信息依赖于为其提供服务的域名。这可以是 [name].letterpress.com 或与完整主机名匹配的自定义域。我们可以通过使用APP_INITIALIZER
.
在引导程序中:
{provide: APP_INITIALIZER, useFactory: (sites:SitesService) => () => sites.load(), deps:[SitesService, HTTP_PROVIDERS], multi: true}),
站点.service.ts:
@Injectable()
export class SitesService {
public current:Site;
constructor(private http:Http, private config:Config) { }
load():Promise<Site> {
var url:string;
var pos = location.hostname.lastIndexOf(this.config.rootDomain);
var url = (pos === -1)
? this.config.apiEndpoint + '/sites?host=' + location.hostname
: this.config.apiEndpoint + '/sites/' + location.hostname.substr(0, pos);
var promise = this.http.get(url).map(res => res.json()).toPromise();
promise.then(site => this.current = site);
return promise;
}
注意:config
只是一个自定义配置类。rootDomain
将
'.letterpress.com'
用于此示例并允许诸如
aptaincodeman.letterpress.com
.
任何组件和其他服务现在都可以Site
注入它们并使用该.current
属性,该属性将是一个具体的填充对象,无需等待应用程序中的任何Promise。
这种方法似乎减少了启动延迟,如果您在等待大型 Angular 包加载,然后在引导程序开始之前等待另一个 http 请求,则启动延迟非常明显。
原来的
您可以使用 Angulars 依赖注入来传递它:
var headers = ... // get the headers from the server
bootstrap(AppComponent, [{provide: 'headers', useValue: headers})]);
class SomeComponentOrService {
constructor(@Inject('headers') private headers) {}
}
或BaseRequestOptions
直接提供准备好
class MyRequestOptions extends BaseRequestOptions {
constructor (private headers) {
super();
}
}
var values = ... // get the headers from the server
var headers = new MyRequestOptions(values);
bootstrap(AppComponent, [{provide: BaseRequestOptions, useValue: headers})]);