【问题标题】:Provide core singleton services module in Angular 2在 Angular 2 中提供核心单例服务模块
【发布时间】:2017-02-14 21:18:10
【问题描述】:

我尝试创建一些核心模块,就像在教程中一样,除了一个细节,我只想提供服务。所以我的 CoreModule 应该像 - 单例服务提供者,因为我不想在 AppModule 中提供大量服务,例如在应用程序版本

import {
  ModuleWithProviders, NgModule,
  Optional, SkipSelf }       from '@angular/core';

import { CommonModule }      from '@angular/common';

import { CommunicatePatientListService }    from './services/communicate_patients_list.service';
import { HTTPPatientsListService }    from './services/http_patients_list.service';
import { SharedService }    from './services/shared_service';


@NgModule({
  imports:      [ CommonModule ],
  providers:    [
    CommunicatePatientListService,
    HTTPPatientsListService,
    SharedService
  ],
  exports: []
})
export class CoreModule {}

更新 2。我尝试了不同的方法来完成提供给我的事情,我发现了一个有趣的时刻。

当我通过标准导入导入 COREModule 单例服务时,它不起作用,但是当我通过 System.js 别名导入它时,它现在可以工作了。我真的很想知道它是如何工作的。这是代码

CoreModule:
import {
  ModuleWithProviders, NgModule,
  Optional, SkipSelf }       from '@angular/core';

import { CommonModule }      from '@angular/common';


import { HeaderModule } from './modules/header/header.module';
import { FooterComponent } from './modules/footer/footer.component';


//THAT DOESNT WORK
// import { CommunicatePatientListService }    from './services/communicate_patients_list.service';
// import { HTTPPatientsListService }    from './services/http_patients_list.service';
// import { SharedService }    from './services/shared_service';
// import { SchedulerSharedService }    from './services/scheduler_shared.service';
// import { FormChangeService }    from './services/on_form_change.service';

//IT IS WORKING NOW
import { CommunicatePatientListService } from '%sharedServices%/communicate_patients_list.service';
import { HTTPPatientsListService } from 'httpPatientsListService';
import { SharedService } from 'sharedService';
import { SchedulerSharedService } from 'schedulerSharedService';
import { FormChangeService } from 'formChangeService';



@NgModule({
  imports:      [
    CommonModule,
    HeaderModule,
  ],
  declarations: [
    FooterComponent
  ],

  exports: [
    FooterComponent,
    HeaderModule
  ]
})
export class CoreModule {

  constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
    if (parentModule) {
      throw new Error(
        'CoreModule is already loaded. Import it in the AppModule only');
    }
  }

  static forRoot(): ModuleWithProviders {
    return {
      ngModule : CoreModule,
      providers:    [
        CommunicatePatientListService,
        HTTPPatientsListService,
        SharedService,
        FormChangeService,
        SchedulerSharedService
      ]
    };
  }


}

患者列表组件

import { Component, Input, OnInit, ViewChild } from '@angular/core';

import { CommunicatePatientListService } from '%sharedServices%/communicate_patients_list.service';
    import { HTTPPatientsListService } from 'httpPatientsListService';
    import { SharedService } from 'sharedService';
    import { SchedulerSharedService } from 'schedulerSharedService';
    import { FormChangeService } from 'formChangeService';

    import { Config } from 'appConfig';
    /* ------- !Config  ---------*/

    const MODULE_NAME: string = 'patients_list';
    const MODULE_PATH: string = `${Config.getProdFolderName()}/modules/patients/${MODULE_NAME}`;


    @Component({
      templateUrl: `${MODULE_PATH}/${MODULE_NAME}.component.html`,
      styleUrls: [`${MODULE_PATH}/${MODULE_NAME}.component.css`,]
    })


    export class PatientsListComponent implements OnInit {
      constructor(
        private patientsListService:HTTPPatientsListService,
        private patsListServCom:CommunicatePatientListService,
        private schedulerSharedService:SchedulerSharedService,
        private sharedService:SharedService
      ) {
  }

【问题讨论】:

  • 如果您将 CoreModule 添加到 AppModules @NgModule() 的导入中,那么它应该可以正常工作。
  • 感谢甘特的帮助。

标签: angular typescript


【解决方案1】:

最好的方法是使用提供者创建模块。请记住,如果您的服务在共享模块中,您可能会获得它的多个实例。那么最好的想法是使用Module.forRoot 配置模块。

按照惯例,forRoot 静态方法既提供又配置 同时服务。它需要一个服务配置对象和 返回一个 ModuleWithProviders。

这里是完整的Doc

仅在根应用程序模块 AppModule 中调用 forRoot。打电话 它在任何其他模块中,特别是在延迟加载的模块中,是 违背本意,很可能会产生运行时错误。

记得导入结果;不要将其添加到任何其他 @NgModule 列表。

@NgModule({
    imports: [CommonModule],
    declarations: [SomeComponent],
    exports: [SomeComponent]
})
export class CoreModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: CoreModule,
            providers: [SomeService]
        };
    }
}

然后导入模块如下:

@NgModule({
  imports: [
    /** other modules import **/
    CoreModule.forRoot(), // you can also pass some config here if needed
    routing
  ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

如果您想防止重新导入 CoreModule

只有根 AppModule 应该导入 CoreModule。坏事 如果延迟加载的模块导入它,就会发生这种情况。

@NgModule({
  imports:      [ CommonModule ],
  declarations: [ SomeComponent ],
  exports:      [ SomeComponent ],
})
export class CoreModule {

  constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
    if (parentModule) {
      throw new Error(
        'CoreModule is already loaded. Import it in the AppModule only');
    }
  }

  static forRoot(config: UserServiceConfig): ModuleWithProviders {
    return {
      ngModule: CoreModule,
      providers: [SomeService]
    };
  }
}

【讨论】:

  • 各种各样的帮助。你能检查我的更新吗?我试图应用这些东西,但它不起作用。谢谢!
  • 现在你用的是什么模块?导入CoreModule.forRoot() 确保您的服务设置正常。并且在所有应用程序中可见。现在,如果您想使用组件或导出的模块。你必须在你想使用它的模块中导入这个模块(如果这个模块不是你已经导入的 AppModule)然后你在没有forRoot 方法的情况下导入这个模块。然后你就可以在这个模块中使用组件了。
  • 我使用了有路由的 patientsModule(它是 LazyLoaded)。在该模块中,我尝试使用 CoreModule 的服务。但是我收到了上面显示的错误。当服务直接在 AppModule 中提供时工作正常。也许不可能通过 CoreModule 向整个应用程序提供单例?
  • 虽然许多组件共享相同的服务实例,但它们依靠 Angular 依赖注入来进行这种共享,而不是模块系统。不要在共享模块中指定应用程序范围的单例提供程序。导入该共享模块的延迟加载模块将制作自己的服务副本。如果 CoreModule 提供 HTTPPatientsListService。 Angular 将该提供程序注册到应用根注入器,使 HTTPPatientsListService 的单例实例可供任何需要它的组件使用,无论该组件是急切加载还是延迟加载。
  • 好的,所以如果我理解你是正确的,要为任何组件(懒惰与否)制作服务真正的单例,我应该提供它 AppModule (RootModule)?这是正确的吗?但是为什么创建CoreModule?如果我应该在AppModule中提供服务,那里可以提供什么东西?我认为在该模块(CoreModule)中我可以提供所有单例并清理我的 AppModule...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 2017-06-21
  • 2018-03-27
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多