Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将具有共享服务的多个angular应用程序的条件boostrap迁移到嵌套的NGM模块_Angular - Fatal编程技术网

将具有共享服务的多个angular应用程序的条件boostrap迁移到嵌套的NGM模块

将具有共享服务的多个angular应用程序的条件boostrap迁移到嵌套的NGM模块,angular,Angular,问题 我正在将RC4迁移到RC5,到目前为止它还可以工作,但由于我必须调整引导程序,我想知道是否有人为我的引导程序(可能是使用ngModules)提供了一个更干净的解决方案,因为对我来说,它有点像黑客 基本上,它引导多个并不总是存在的组件,这取决于它们是否在页面上,并且它确保在组件及其子组件之间共享配置/帮助程序。我可以直接将这3个组件包装到ngModules中,但是我仍然需要将共享服务注入到模块中。是否有办法将所有3个组件封装到一个模块中,并仅在页面上提供这些组件时引导它们?我也没有在ngMo

问题

我正在将RC4迁移到RC5,到目前为止它还可以工作,但由于我必须调整引导程序,我想知道是否有人为我的引导程序(可能是使用ngModules)提供了一个更干净的解决方案,因为对我来说,它有点像黑客

基本上,它引导多个并不总是存在的组件,这取决于它们是否在页面上,并且它确保在组件及其子组件之间共享配置/帮助程序。我可以直接将这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);
}
部分解决方案

我找到了一种翻译这个概念的方法:

main.ts很简单,如文档所述:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }              from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
模块本身不使用引导注释,因为这不能有条件地完成,因此您可以只使用声明,以便了解潜在的起点并手动实现引导:

@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);
        }
    }
}
服务配置可以在模块构造函数中处理,注入可以像以前一样手动完成但是引导方法是去润滑的,因此我将ngDoBootstrap的最后一部分更改为此(作为测试,忽略上面两个):

模块本身相当简单:

@NgModule({
    imports: [ BrowserModule ],
    declarations: [ EnterpriseSearchComponent ],
    bootstrap: [ EnterpriseSearchComponent ]
})
export class EnterpriseSearchModule { }

我现在有一个问题,自动引导的组件无法解析配置服务,尽管它被显式地作为提供者提供给包装模块。这对我来说似乎是一个角度错误,还是我只是做错了什么?

ngDoBootstrap生命周期钩子不是这样工作的。您所期望的是类似于
ngOnBootstrap
ngAfterBootstrap
ngOnInit
的东西,但它们都不能在NgModule上工作。对于
ngDoBootstrap

ngDoBootstrap(moduleRef){
const appRef=模块ref.injector.get(ApplicationRef);
//不知何故,可能从entryComponents获取compFactory
//引导每个入口组件
appRef.bootstrap(compFactory);
}
但是,
ApplicationRef#bootstrap
有一个问题,因为它不再需要注入器或提供者。您最好在NgModule之外执行此操作,并为每个应用程序创建一个NgModule。或者在ngDoBootstrap中使用Di来获取您的服务,它是在引导过程中创建的,而不是以后创建的

moduleRef.injector.get(MyService);//这确保了服务是在引导过程中创建的,而不是稍后其他东西注入服务时创建的

@NgModule({
    imports: [ BrowserModule ],
    declarations: [ EnterpriseSearchComponent ],
    bootstrap: [ EnterpriseSearchComponent ]
})
export class EnterpriseSearchModule { }