简体   繁体   English

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

[英]Angular 2, share an object between two components that have no direct relationship

I have an app that is structured like this. 我有一个像这样结构的应用程序。

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

In component-b some data is retrieved and later set to a new object. component-b中,检索一些数据,然后将其设置为新对象。 For example, something like this.. 例如,像这样的东西..

 {
    infoThatComponentANeeds    : true,
    someMoreInfoAddedFromCompB : []
 }

This info is needed for the template in component-a . component-a -a中的模板需要此信息。 At first I tried to pass the info up to component-a via @Outuput and eventEmitter using a custom event. 起初我尝试使用自定义事件通过@Outuput和eventEmitter将信息传递给component-a But I was unable to get it to bubble up. 但我无法让它冒出来。 I suspect that has to do with it being loaded through the router. 我怀疑这与通过路由器加载它有关。 So now I am trying to share the data between the two components using a shared service. 所以现在我尝试使用共享服务在两个组件之间共享数据。

My Service So Far: 我的服务到目前为止:

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;
    }
}

This is how I am trying to use it in component-a: 这就是我试图在component-a中使用它的方法:

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

The Problem: 问题:

After the spec is set in component-b and ngDoCheck from component-a checks to see if the spec has been set. component-b设置规范并从component-a设置ngDoCheck ,检查是否已设置规范。 It comes back as undefined so the getSpec() function does not run, and no spec is returned. 它返回为undefined因此getSpec()函数不会运行,并且不返回任何规范。 So I am not sure what I am missing, or why it would still be undefined in my SharedService after it has been set. 所以我不确定我缺少什么,或者为什么在设置之后我的SharedService仍然undefined它。 Should the shared service keep a reference to what was set? 共享服务是否应该保留对所设置内容的引用? Or am I completely misunderstanding this concept? 还是我完全误解了这个概念?

I have also explored ways of sharing this data via promises/observables. 我还探讨了通过promises / observables共享这些数据的方法。 However I have not had any luck with that either. 但是,我也没有任何运气。 And the majority of the examples I have found use HTTP, which I really do not need at this point. 我发现的大多数示例都使用HTTP,我现在真的不需要。

Update: 更新:

Here is some more info. 这是一些更多的信息。

Boot.ts 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 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(){}
}

Update 2: 更新2:

Here is a plunker I created to try to isolate the issue. 这是我创建的一个试图隔离问题的plunker。 I removed the router stuff and simplified the whole thing. 我删除了路由器的东西,简化了整个过程。 I am still seeing the same result.. 我仍然看到相同的结果..

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

Watch the console.log() 观看console.log()

Fixed: 固定:

This was the key. 这是关键。

Be sure to remove configurations in the providers attribute of your two components. 请务必删除两个组件的providers属性中的配置。

Perhaps your service isn't actually shared. 也许您的服务实际上并未共享。 I mean you could have two instances according to the way you configured providers. 我的意思是,根据您配置提供程序的方式,您可以有两个实例。

To be sure, just add the service when bootstrapping your application: 可以肯定的是,只需在引导应用程序时添加服务:

bootstrap(AppComponent, [ SharedService ]);

Be sure to remove configurations in the providers attribute of your two components. 请务必删除两个组件的providers属性中的配置。

If you're interested in hierarchical injectors of Angular2 (the concept behind this), you could have a look at this question: 如果你对Angular2的分层注入器(这背后的概念)感兴趣,你可以看一下这个问题:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM