2016-06-07 75 views
2

中的数组,我们可能有一个不寻常的angular2体系结构,我们在单个页面上引导多个组件(小部件),而不是处理所有内容的单个应用程序组件。Angular2 Bootstrap Providers vs首先提供组件

我的第一个问题是,以下两种实现方式是否相同,从我的理解,他们是(请纠正我,如果我误解的东西):

bootstrap(SomeComponent, [HTTP_PROVIDER, FooService, ServiceNeededByFoo]) 

这初始化SomeComponent并提出了提供者那里的三项服务。这样SomeComponent就可以在它自己的构造函数中解析FooService,并且FooService可以解析ServiceNeededByFoo,因为它在SomeComponent(父类)中查找它。从我的理解这应该是完全一样的,FooService接口和ServiceNeededByFoo一个新的实例

bootstrap(SomeComponent) 

所以:

如果我定义

providers: [HTTP_PROVIDER, FooService, ServiceNeededByFoo] 

内SomeComponent,我可以像这样初始化在SomeComponent级别创建并与SomeComponent的所有子节点共享,这些子节点也需要FooService。如果相同,是否有任何优先/推荐的方式?

第二个问题就是现在,我怎么可以在不在同一个层次DI组件共享FooService接口的单一实例:

bootstrap(SomeComponent1, FooService) 
bootstrap(SomeComponent2, FooService) 

其中FooService接口应该是相同的实例。喜欢的东西:

var foo = new FooService(); 
foo.expensiveInit(); 
bootstrap(SomeComponent1, provide(FooService, {instance: foo})) 
bootstrap(SomeComponent2, provide(FooService, {instance: foo})) 

回答

1

仅供参考,如果有人绊倒在这个帖子,也有一些问题,共享的情况下,当没有中心的应用程序组件。

我的最终实现是这样的,它与需要注射服务本身就是一个简单的服务的服务为例:

var cs = new ConfigurationService(); 
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})]; 

if ($('notification-widget').length > 0) { 
    bootstrap(NotificationWidgetComponent, defaultProviders); 
} 

if ($('livesearch-widget').length > 0){ 
    bootstrap(LivesearchWidgetComponent, defaultProviders); 
} 
+0

提供mehods和Provider类现在是rc3的depricates,我还没有找到替换,因为代码中的注释简单地说“TODO:improve docs” – Tom

2

角DI产生根源在哪里被bootstrap()创建和供应商传递给bootstrap()喷油器的层次结构。
默认由角提供的所有东西被添加到该喷射器以及(如PLATFORM_PIPESPLATFORM_DIRECTIVES,...)

然后从根组件的子注入与在根组件提供的供应商开始创建。对于每个子组件和根组件指令,都会创建子注入器,直至叶子组件和指令。

喷油器层次结构因此类似于您的组件和指令层次结构。

当组件需要依赖项(构造函数参数)时,DI在它的注入器提供程序上查找它。如果找不到它,它会检查父喷嘴,然后继续执行由bootstrap()创建的根喷嘴。

这应该很清楚地表明bootstrap()的提供者或根组件的提供者导致了完全相同的行为。

您分享两个独立的自举部件之间的服务方式似乎没什么问题,但据我所知,应该是useValue代替instance

bootstrap(SomeComponent1, provide(FooService, {useValue: foo})) 

参见

如上所述,如果您使用observabl发出值e在共享服务中,值将在发件人区域中发出,而其他应用程序中的订阅者在发件人区域中被调用。确保您使用zone.run

constructor(sharedService:FooService, zone:NgZone) { 
    sharedService.someObservable.subscribe(value => { 
    zone.run(() => { 
     this.data = value; 
     this.router.navigate... 
     ... 
    }); 
    }); 
} 
+0

感谢详尽的解释!特别是最后的例子。 – Tom