当前位置: 首页 > 知识库问答 >
问题:

使用Angular2中的服务在组件之间共享数据

丁学
2023-03-14

我正在使用angular2开发一个应用程序。我有一个场景,需要在路由时(使用router.navigate())将复杂的数据(对象数组)从一个组件传递到另一个组件(它们不是父子关系,而是两个独立的组件)。我在谷歌上搜索过,大多数结果描述了父子组件的场景。我浏览了结果,找到了这些传递数据的方法。

1)创建共享服务2)通过路由参数

第二种方法适合我(尽管我不喜欢上面解释的复杂数据)。我无法使用共享服务共享数据。所以我的问题是,使用服务在组件之间传递数据是否只在组件处于父子关系时有效?另外,让我知道是否有其他更喜欢的方式在一个组件和另一个组件之间传递数据?

已更新:我正在从我的方案中添加一些代码。请让我知道我的错误,为什么通过共享服务传递数据不起作用。

我有2个组件:1)SearchComponent 2)TransferComponent我正在search component中设置数据,并希望通过utilityService访问transfer component中的数据。

公用事业服务:

import {Injectable} from "@angular/core";

@Injectable()
export class UtilityService{
    constructor(){

    }
    public bioReagentObject = [];

    routeBioReagentObj(bioReagentObj){
        console.log("From UtilityService...", bioReagentObj);
        for (let each of bioReagentObj)
            this.bioReagentObject.push(each)
        // console.log("From UtilityService",this.bioReagentObject);
    }

    returnObject(){
        console.log("From UtilityService",this.bioReagentObject);
        return this.bioReagentObject
    }



}

searchcomponent.ts

    import {UtilityService} from "../services/utilityservice.component";
    import {Component, OnInit, OnDestroy, Input} from '@angular/core';

@Component({
    selector: 'bioshoppe-search-details',
    providers: [UtilityService],
    templateUrl: 'app/search/searchdetails.component.html',
    styleUrls: ['../../css/style.css']
})

export class SearchDetailsComponent implements OnInit, OnDestroy {
    constructor(private route: ActivatedRoute,
                private utilityService: UtilityService,
                private router: Router) {

    }
    @Input() selected: Array<String> = [{barcode:123, description:"xyz"}];

       //This method is called from .html and this.selected has the data to be     shared.
       toTransfer() {
        this.utilityService.routeBioReagentObj(this.selected);
        this.router.navigate(['/transfer']);

    }
}

TransferService.ts

import {Component, Input, OnInit, OnDestroy} from '@angular/core';
import {TransferService} from "../services/transferservice.component";
import {UserService} from "../services/userservice.component";
import {SearchService} from "../services/searchservice.component";
import {ActivatedRoute} from '@angular/router';
import {UtilityService} from "../services/utilityservice.component";


@Component({
    selector: 'bioshoppe-transfer',
    providers: [TransferService, UserService, SearchService, UtilityService],
    templateUrl: 'app/transfer/transfer.component.html',
    styleUrls: ['../../css/style.css', '../../css/transfer.component.css']
})

export class TransferComponent implements OnInit, OnDestroy{
    constructor(private transferService: TransferService,
                private userService: UserService,
                private searchService: SearchService,
                private utilityService: UtilityService,
                private route: ActivatedRoute
    ) {

    }
ngOnInit() {
// I am trying to access the data here, but it print "undefind"
console.log("From Transferpage",this.utilityService.returnObject());
}
}

我肯定有什么地方不对劲,但我就是想不出来。感谢任何帮助。

共有3个答案

经俊茂
2023-03-14

您可以通过使用Observable在两个组件之间共享数据来实现这一点。

我没有写这篇文章,但它很有用

一个快速的帖子,展示了一个让我卡了一段时间的例子 - 如何在Angular 2/4中的组件之间进行通信。

解决方案是使用可观察量和主体(这是一种可观察性)

http://jasonwatmore.com/post/2016/12/01/angular-2-communicating-between-components-with-observable-subject

臧亦
2023-03-14

您需要区分服务何时来自NgModule,或者何时来自其他组件。

基础

在Angular2 compon的分层树

它是如何工作的

注入器的作用是将你在构造器中定义的服务注入到你的组件中,即找到它,如果找不到就启动并提供给你。当你把你想要的服务放入构造函数中时,它会从你的组件到根(即NgModule)查看注入器树中是否存在服务。如果injector发现该服务有一个已定义的提供者,但没有服务实例,它将创建该服务。如果没有供应商,价格会继续上涨。

到目前为止您已经看到了

你看到的是父组件德

一些多余的

通常,如果您想注入服务并且无法一直到root找到它,那么在编译/运行时期间会出现错误。但是,如果您定义要注入可选服务,则如果找不到此服务的提供程序,注入器不会失败。

或多或少

一些有用的链接:

> < Li > < p > https://angular . io/docs/ts/latest/guide/hierarchical-dependency-injection . html

https://blog.thoughtram.io/angular/2015/05/18/depe

耿志义
2023-03-14

卡马龙是对的。你的错误是你声明了两次实用程序服务

  1. 一旦进入SearchComponent的提供商。
  2. 一旦进入TransferComponent的提供商。

您应该只声明一次服务,以确保两个组件获得相同的实例。为此,您可以选择以下任一选项:

    < li >在声明中同时包含< code>SearchComponent和< code>TransferComponent的< code>@NgModule的提供程序中声明服务。十有八九这是正确的解决方案! < li >在< code>@Component的提供程序中声明服务,该提供程序是< code>SearchComponent和< code>TransferComponent的父级。根据组件树的外观,这可能不可行。

以下选项# 1,你最终得到的:

@NgModule({
  imports: [CommonModule, ...],

  // Look, the components injecting the service are here:
  declarations: [SearchComponent, TransferComponent, ...],

  // Look, the service is declared here ONLY ONCE:
  providers: [UtilityService, ...]
})
export class SomeModule { }

然后注入<代码> UtilityService > < /代码在你的公司

@Component({
  selector: 'foo',
  template: '...',
  providers: []  // DO NOT REDECLARE the service here
})
export class SearchComponent {
  constructor(private utilityService: UtilityService) { }
}

@Component({
  selector: 'bar',
  template: '...',
  providers: []  // DO NOT REDECLARE the service here
})
export class TransferComponent {
  constructor(private utilityService: UtilityService) { }
}
 类似资料:
  • 寻找一种方法,使服务在必要时将最新数据提供给订阅的组件。例如:组件 3 将更改写入 API 以下是一些片段和一些描述,说明到目前为止我所做的工作: 该服务通过HTTP从API获取数据。组件1和组件2订阅了服务返回的observable:

  • 问题内容: 有没有办法在AngularJS中的服务之间共享数据? 用例:来自不同服务的数据聚合 例如,我想要一个service1从REST服务加载一些数据。然后,另一个service2将来自另一个REST API的其他数据添加到service1数据中,以创建数据聚合服务。 我基本上是想根据它们使用的API来分离服务,但是仍然有一个服务来最终保存所有数据。 问题答案: 创建使用延迟库的第三项服务,以

  • 我有两个组件A和B,其中组件A包含一个按钮。我希望当用户点击这个按钮时,在组件B上启动一个功能 组件 B 使用路由渲染。我正在考虑使用带有可观察布尔值的服务,该布尔值指示是否单击了 A 中的按钮。这是实现它的正确方法吗?

  • 问题内容: 我正在开发使用Meteor和React作为视图引擎的应用程序 考虑下图: 从另一个示例反应隐藏组件 当触发C4按钮单击事件时,我需要更改C2组件状态。由于他们没有直接关系,因此我无法直接从C4进入C2状态。 另一个示例是从Component提交表单并获取在另一个Component中声明的数据(输入字段的值)。 我知道可以通过一些技巧来解决此问题(例如,流星会话,通过每个组件传递数据,基

  • 当前体系结构: 问题: 我们在前端和后端层之间有一个两步流程。 null 微服务2(MS2)需要验证I1的完整性,因为它来自前端。如何避免对MS1进行新的查询?最好的办法是什么? 我试图优化的流删除了步骤1.3和2.3 流程1: null 流程2: 2.1用户X已在本地/会话存储中存储了数据(MS2_Data) 2.2用户X在MS1上保留数据(MS2_Data+MS1_Data) 2.3 MS1使

  • 我可能遗漏了一些非常明显的东西,但我想做的是在组件之间异步共享从服务器获取的数据。 我的服务看起来是这样的: 因为流程是异步的,所以我需要promise响应,但是promise的响应返回实际的subscribe对象,而不是返回的< code>data.json。 这是一个配置文件页面,它由嵌套路由组成,所以我不能将数据传递给路由组件。路由组件之一是帖子,加载配置文件后,它应该开始获取服务中当前用户