Angular 2,在没有直接关系的两个组件之间共享对象

问题描述:

我有一个像这样构建的应用程序。Angular 2,在没有直接关系的两个组件之间共享对象

<app> 
    <header> 
     <component-a></component-a> 
    </header> 
    <div> 
    <router-outlet></router-outlet> 
    <component-b></component-b> <!-- loaded through router --> 
    </div> 
</app> 

component-b一些数据被检索,后来设置为一个新的对象。例如,像这样的东西..

{ 
    infoThatComponentANeeds : true, 
    someMoreInfoAddedFromCompB : [] 
} 

此模板需要component-a的信息。起初我试图通过@Outuput and eventEmitter使用自定义事件将信息传递给component-a。但我无法让它冒出来。我怀疑这与它通过路由器加载有关。所以现在我试图使用共享服务来共享这两个组件之间的数据。

我的服务至今:

import {Injectable} from 'angular2/core'; 

@Injectable() 
export class SharedService 
{ 
    public spec:Spec= null; 

    public getSpec() 
    { 
     return this.spec; 
    } 
    public setSpec(spec:Spec) 
    { 
     this.spec = spec; 
    } 
} 

这是我正在尝试在组件的一个使用它:

ngDoCheck() 
{ 
    if(this._sharedService.spec) 
    { 
     this.spec= this._sharedService.getSpec(); 
    } 
} 

问题:

规格设定在component-b和之后从component-a检查以查看是否已设置规范。它返回为undefined,所以getSpec()函数不运行,并且不返回规范。所以我不确定我错过了什么,或者为什么在SharedService设置后它仍然是undefined。共享服务是否应该参照设定的内容?或者我完全误解了这个概念?

我也探索过通过promise/observables共享这些数据的方法。不过,我还没有任何运气。而且我发现的大多数例子都使用了HTTP,在这一点上我真的不需要这些。

更新:

下面是更多的一些信息。

Boot.ts

import {bootstrap} from 'angular2/platform/browser'; 
import {HTTP_PROVIDERS} from 'angular2/http'; 
import { 
    ROUTER_PROVIDERS, 
    APP_BASE_HREF, 
    Location, 
    LocationStrategy, 
    HashLocationStrategy, 
    PathLocationStrategy 
} from 'angular2/router'; 

import {AppComponent} from './components/app.component'; 
import {SharedService} from './services/shared.service'; 

bootstrap(<any>AppComponent, [ 
    ROUTER_PROVIDERS, 
    SharedService, 
    provide(LocationStrategy, {useClass: PathLocationStrategy}) 
]); 

AppComponent.ts

import {AfterViewInit, Component, OnInit} from 'angular2/core'; 
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'; 
import {ComponentA} from './componentA'; 


@Component({ 
    selector : 'body', 
    directives : [ComponentA, ROUTER_DIRECTIVES], 
    template : ` 
     <app> 
      <header> 
       <component-a></component-a> 
      </header> 
      <div> 
       <router-outlet></router-outlet> 
      </div> 
     </app> 
    ` 
}) 

@RouteConfig([ 
    {path: '/:appName/', name: 'ComponentB', component: ComponentB} 
]) 

export class AppComponent 
{ 
    constructor(){} 
} 

更新2:

这里是我创建的尝试隔离问题上plunker。我删除了路由器的东西,并简化了整个事情。我仍然看到同样的结果..

https://plnkr.co/edit/kx6FWWGS1i04bH5J9DXM?p=preview

观看console.log()

修正:

这是关键。

务必删除 两个组件的providers属性中的配置。

也许你的服务并没有实际共享。我的意思是根据配置提供者的方式,你可以有两个实例。

可以肯定的,只是这样引导您的应用程序时添加的服务:

bootstrap(AppComponent, [ SharedService ]); 

一定要删除你的两个组件的providers属性配置。

如果你有兴趣Angular2(这背后的概念)的分层喷射器,你可以看一下这个问题:

+0

谢谢您的答复。我其实也尝试过。仍然没有运气。尽管可以确定,但我会再次尝试。 –

+0

你可以添加组件的配置吗?而你推动你的应用程序的方式......谢谢! –

+0

另一件事是可以肯定,当你更新/根据你利用的钩子方法获得价值(ngOnInit,ngDoCheck,...) –