Angular 2如何为延迟加载的模块提供单例服务

Bee*_*ice 8 module typescript angular2-services angular

根据我的理解Angular 2 rc5,要从另一个模块(不是AppModule)作为单个模块提供服务到每个组件,即使是那些延迟加载的模块,我们也不会将该服务包含在该providers模块的其他模块中.我们改为导出它RouterModule.forRoot()并导入结果AppModule

根据文件:

SharedModule应仅在根AppModule导入时提供UserService.SharedModule.forRoot方法帮助我们应对这一挑战...... SharedModule没有providers...当我们将SharedModule添加到AppModule的导入时,我们调用forRoot.这样,AppModule获得导出的类,SharedModule同时提供单例UserService提供程序

我真的很挣扎如何为延迟加载的路由提供第三方服务(imports我的数组中的模块使用的服务AppModule).我无法控制这个第三方模块,所以我不能只从该NgModule.providers模块的数组中删除该服务,并将其放入RouterModule.forRoot()我的服务中.

具体的服务MdIconRegistry,这是providersMdIconModuleAngular Material 2 alpha 7-3.此服务用于注册svg图标,然后可以使用<md-icon svgIcon='iconName'>标记显示在页面上.所以:

  • MdIconModule在我的根目录中导入AppModule
  • 我使用有问题的服务来注册我的svg图标 AppComponent

该图标可见并且运行良好,但仅限于启动时加载的模块.延迟加载的模块无法看到这些图标,因此我怀疑Angular注入器不会注入相同的MdIconRegistry服务实例.

tl; dr:我怎样才能从第三方模块中将服务作为我的延迟加载组件的单例?

这是一个演示问题的编码器(编码typescript).

PS:这引起了github上MdIconModule开发人员的注意.

Jam*_*mes 10

I do not think it has anything to do with the component being lazy-loaded.
Run Code Online (Sandbox Code Playgroud)

LazyLoadedComponent不是AppModule的一部分 - 它是LazyModule的一部分.根据文档,组件只能是一个模块的一部分.如果您也尝试将LazyLoadedComponent添加到AppModule,则会出现相应的错误.所以LazyLoadedComponent甚至根本没有看到MdIconModule.您可以通过查看调试器中的模板输出来确认这一点 - 它没有改变.

<md-icon svgIcon="play"></md-icon>
Run Code Online (Sandbox Code Playgroud)

解决方案似乎是将MdIconModule添加到LazyModule,虽然仅此一项不能解决问题,但它确实会在输出中添加错误.

检索图标时出错:错误:无法找到名称为":play"的图标

现在模板输出看起来像这样,所以我们知道它正在加载.

<md-icon role="img" svgicon="play" ng-reflect-svg-icon="play" aria-label="play"></md-icon>
Run Code Online (Sandbox Code Playgroud)

我从LazyLoadedComponent添加了对addSvgIconSet的调用,并且它使它工作...所以这证明每个组件有一个MdIconRegistry服务的实例 - 不是你想要的,但可能指向正确的方向.

这是新的插件 - http://plnkr.co/edit/YDyJYu?p=preview

经过进一步审核后,我在文档中发现了这一点:

为什么延迟加载的模块中提供的服务仅对该模块可见?

与启动时加载的模块的提供者不同,延迟加载的模块的提供者是模块范围的.

最后更新!这是答案.没有为延迟加载的组件正确设置MdIconModule ...但我们可以轻松创建我们自己的模块,该模块已正确设置并使用它.

import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';

import { MdIcon } from '@angular2-material/icon';
import { MdIconRegistry } from '@angular2-material/icon';

@NgModule({
  imports: [HttpModule],
  exports: [MdIcon],
  declarations: [MdIcon]
})
export class MdIconModuleWithProviders {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: MdIconModuleWithProviders,
      providers: [ MdIconRegistry ]
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

Plunk更新并完全正常工作.(对不起,更新了同一个) - > http://plnkr.co/edit/YDyJYu?p=preview

有人可能会提交拉取请求,以便Angular Material导出两种样式的模块.