首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将单例服务提供给延迟加载的模块

如何将单例服务提供给延迟加载的模块
EN

Stack Overflow用户
提问于 2016-08-18 05:39:09
回答 2查看 5.6K关注 0票数 8

根据我对Angular 2 rc5的理解,为了使来自另一个模块(而不是AppModule)的服务可以作为单个组件提供给每个组件,即使是那些延迟加载的组件,我们不包括该其他模块的providers数组中的服务。相反,我们使用RouterModule.forRoot()导出它,并在AppModule中导入结果

根据医生的说法

SharedModule只应在根AppModule导入时提供UserService。SharedModule.forRoot方法帮助我们满足这个challenge...the SharedModule不具有providers...When,我们将SharedModule添加到AppModule的导入中,我们称之为forRoot。在此过程中,AppModule获取导出的类,SharedModule同时交付单例UserService提供程序。

我真的很难让第三方服务(AppModuleAppModule数组中的一个模块使用的服务)可以用于延迟加载的路由。我无法控制这个第三方模块,所以我不能就这样从该模块的NgModule.providers数组中删除该服务,并将其放置在RouterModule.forRoot()中,就像我使用我的服务一样。

特定的服务是MdIconRegistry,它位于providers中,用于MdIconModule of Angular Material 2 alpha 7-3。此服务用于注册svg图标,然后可以使用<md-icon svgIcon='iconName'>标记在页面上显示这些图标。所以:

  • 我在根MdIconModule中导入了AppModule
  • 我使用该服务在我的AppComponent中注册svg图标。

图标是可见的,工作良好,但只在启动时加载的模块中。延迟加载的模块看不到这些图标,因此我怀疑角注入器没有注入相同的MdIconRegistry服务实例。

tl;dr:,我如何使第三方模块中的服务成为我的惰性加载组件可以使用的单例服务?

下面是一个演示这个问题的柱塞 (以typescript编码)。

PS:这引起了MdIconModule developer 在github。的注意。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-18 17:57:28

代码语言:javascript
复制
I do not think it has anything to do with the component being lazy-loaded.

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

代码语言:javascript
复制
<md-icon svgIcon="play"></md-icon>

解决方案似乎是将MdIconModule添加到LazyModule中,虽然这本身并不能解决问题,但它确实给输出添加了一个错误。

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

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

代码语言:javascript
复制
<md-icon role="img" svgicon="play" ng-reflect-svg-icon="play" aria-label="play"></md-icon>

我从LazyLoadedComponent添加了对LazyLoadedComponent的调用,这使它能够运行…因此,这证明了每个组件都有一个MdIconRegistry服务实例--不是您想要的,但可能会指向正确的方向。

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

经过进一步的回顾,我在文档中找到了这个

为什么延迟加载模块中提供的服务只对该模块可见? 与启动时加载的模块提供程序不同,延迟加载模块的提供程序是模块作用域。

最后更新!这是答案。对于延迟加载的组件,MdIconModule没有正确设置.但是我们可以很容易地创建我们自己的模块,并正确地设置并使用它。

代码语言:javascript
复制
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 ]
    };
  }
}

更新和充分发挥作用。(对不起,更新了相同的) -> http://plnkr.co/edit/YDyJYu?p=preview

一个人可以提交一个拉力请求,这样的角度材料出口模块的两种风格。

票数 11
EN

Stack Overflow用户

发布于 2018-06-08 14:32:40

新的角度6有一种新的方式来注册一个提供者作为一个单例。在服务的@Injectable()装饰器中,使用providedIn属性。将其值设置为“根”。然后不需要将其添加到根模块的提供程序列表中,或者在本例中也可以将其设置为MdIconModuleWithProviders模块,如下所示:

代码语言:javascript
复制
@Injectable({
  providedIn: MdIconModuleWithProviders // or 'root' for singleton
})
export class MdIconRegistry {
...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39010654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档