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

标签 javascript angular

我有一个结构如下的应用。

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

这就是我尝试在组件 a 中使用它的方式:

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

问题:

component-b 中设置规范后,component-a 中的 ngDoCheck 检查是否已设置规范。它返回为 undefined,因此 getSpec() 函数不会运行,也不会返回任何规范。所以我不确定我遗漏了什么,或者为什么它在我的 SharedService 设置后仍然是 undefined 。共享服务是否应该保留对设置内容的引用?还是我完全误解了这个概念?

我还探索了通过 promises/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()

固定:

这是关键。

Be sure to remove configurations in the providers attribute of your two components.

最佳答案

也许您的服务实际上并未共享。我的意思是,根据您配置提供程序的方式,您可以有两个实例。

可以肯定的是,只需在引导应用程序时添加服务即可:

bootstrap(AppComponent, [ SharedService ]);

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

如果你对 Angular2 的分层注入(inject)器(这背后的概念)感兴趣,你可以看看这个问题:

关于javascript - Angular 2,在没有直接关系的两个组件之间共享一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36943952/

相关文章:

javascript - 如何将这两个 CoffeeScript 片段合并到 1 个有效的文件中?

javascript - 如何在 JavaScript 中模拟目标 ="_blank"

Angular 2 : ngSwitch or ViewContainerRef. createComponent

Angular 11 SSR 已编译,但在 prod 构建和服务方面存在问题,浏览器中未显示任何内容

javascript - 如何声明 typescript 中可能不存在的变量?

Javascript:替换字符串函数在 IE7-8 中不起作用

javascript - 迭代对象的关联数组

javascript - 带有局部参数的 onclick 全局函数

jquery - Webpack安装包后编译失败错误

json - Angular 5 Observable映射到Json数组