问题
我正在将RC4迁移到RC5,到目前为止它仍然有效,但是因为我必须调整引导程序,无论如何我想知道是否有人为我的引导程序(可能使用ngModules)有一个更清洁的解决方案,因为对我来说它感觉有点hackish.
基本上它会引导多个组件,这些组件并不总是存在,具体取决于它们是否在页面上,并确保组件及其子组件之间共享配置/帮助程序.我可以直接将3个组件包装到ngModules中,但是我仍然需要将共享服务注入模块.有没有办法将所有3个组件包装到一个模块中,只有当它们在页面上可用时才引导它们?我也没有在ngModule中看到一个init钩子,我可以在将它们注入子组件之前预先配置它们.
这是我以前的main.ts中的相关部分:
var cs = new ConfigurationService();
var hs = new HelperService(cs);
var injector = ReflectiveInjector.resolveAndCreate([TranslateService,
{provide: TranslateLoader, useClass: JsonLoader}, HTTP_PROVIDERS]);
var ts = injector.get(TranslateService);
ts.setDefaultLang('en');
ts.use(cs.getLanguage());
var defaultProviders = [
{provide: TranslateService, useValue: ts},
{provide: ConfigurationService, useValue: cs},
{provide: HelperService, useValue: hs}
];
if ($('notification-widget').length > 0) {
bootstrap(NotificationWidgetComponent, defaultProviders);
}
if ($('livesearch-widget').length > 0){
bootstrap(LivesearchWidgetComponent, defaultProviders);
}
if ($('enterprise-search').length > 0){
bootstrap(EnterpriseSearchComponent, defaultProviders);
}
Run Code Online (Sandbox Code Playgroud)
部分解决方案
我找到了一种翻译概念的方法:
main.ts很简单,如文档所述:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
Run Code Online (Sandbox Code Playgroud)
模块本身不使用引导程序注释,因为这不能有条件地完成,您可以只使用声明,因此angular知道潜在的起点并手动实现引导程序:
@NgModule({
imports: [ BrowserModule ],
declarations: [ NotificationWidgetComponent, LivesearchWidgetComponent, EnterpriseSearchComponent ],
providers: [ConfigurationService, HelperService, TranslateService,
{provide: TranslateLoader, useClass: JsonLoader}]
})
export class AppModule {
constructor(
private conf: ConfigurationService,
private trans: TranslateService,
private help: HelperService
){
this.trans.setDefaultLang('en');
this.trans.use(this.conf.getLanguage());
}
ngDoBootstrap(){
let providers = [
{provide: ConfigurationService, useValue: this.conf},
{provide: HelperService, useValue: this.help},
{provide: TranslateService, useValue: this.trans}
];
if ($('notification-widget').length > 0) {
bootstrap(NotificationWidgetComponent, providers);
}
if ($('livesearch-widget').length > 0){
bootstrap(LivesearchWidgetComponent, providers);
}
if ($('enterprise-search').length > 0){
bootstrap(EnterpriseSearchComponent, providers);
}
}
}
Run Code Online (Sandbox Code Playgroud)
可以在模块构造函数中处理服务配置,并像以前一样手动完成注入.然而,bootstrap方法被删除,所以我将ngDoBootstrap的最后一部分更改为此(仅作为测试,忽略上面的两个):
if ($('enterprise-search').length > 0){
platformBrowserDynamic().bootstrapModule(EnterpriseSearchModule, {providers: providers});
}
Run Code Online (Sandbox Code Playgroud)
模块本身很简单:
@NgModule({
imports: [ BrowserModule ],
declarations: [ EnterpriseSearchComponent ],
bootstrap: [ EnterpriseSearchComponent ]
})
export class EnterpriseSearchModule { }
Run Code Online (Sandbox Code Playgroud)
我现在遇到的问题是,自动引导组件无法解析配置服务,尽管它明确地作为提供程序提供给包装模块.这对我来说似乎是一个有角色的错误,或者我只是做错了什么?
生命周期钩子ngDoBootstrap不是这样工作的。你所期望的是类似的东西ngOnBootstrap,ngAfterBootstrap或者ngOnInit它们都不能在 NgModule 上工作。因为ngDoBootstrap你想做的是
ngDoBootstrap(moduleRef) {
const appRef = moduleRef.injector.get(ApplicationRef);
// somehow grab compFactory probably from entryComponents
// bootstrap each entryCoponent
appRef.bootstrap(compFactory);
}
Run Code Online (Sandbox Code Playgroud)
但有一个问题,因为ApplicationRef#bootstrap它不再需要注入器或提供者。您最好在 NgModule 之外执行此操作,并为每个应用程序创建一个 NgModule。或者在 ngDoBootstrap 中使用 Di 来获取您的服务,这样它是在引导期间而不是稍后创建的
moduleRef.injector.get(MyService); // this makes sure that the service is created during bootstrap rather than later when something else injects it
| 归档时间: |
|
| 查看次数: |
1517 次 |
| 最近记录: |