使用Angular2中的服务在组件之间共享数据 [英] Share data between components using a service in Angular2

查看:60
本文介绍了使用Angular2中的服务在组件之间共享数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用angular2开发应用程序.我有一个场景,我需要在路由时(使用router.navigate())将复杂的数据(对象数组)从一个组件传递到另一个组件(它们不是父子组件,它们是两个单独的组件).我已经用谷歌搜索了,大多数结果描述了父子组件的情况.我查看了结果,发现了这些传递数据的方法.

I am developing an application using angular2. I have a scenario where I need to pass complex data (array of objects) from one component to another component(they are not parent-child, they are two separate components) while routing(using router.navigate()). I have googled this and most of the results describe the scenario of components that are parent-child. I have gone through the results and found these ways to pass the data.

1)创建共享服务 2)通过作为路径参数

1) Create Shared Service 2) Pass as route parameters

第二种方法对我有效(尽管如上所述,当我拥有复杂的数据时,我不喜欢这样).我无法使用共享服务共享数据. 所以我的问题是,仅当组件处于父子关系时才使用服务在组件之间传递数据吗?另外,请问是否还有其他首选的方式可以在一个组件和另一个组件之间传递数据?

2nd approach works for me (even though, I don't like that when I have complex data as explained above). I am not able to share the data using shared service. So my questions is, does passing data between components using services only works when components are in parent-child relationship? Also, let me know if there are other prefered ways to pass data between one component and other?

已更新: 我从场景中添加了一些代码.请让我知道我为什么无法通过共享服务传递数据的错误.

Updated: I am adding bit of code from my scenario. Please let me know my mistake as to why passing data through shared services is not working.

我有2个组件:1)SearchComponent 2)TransferComponent 我正在SearchSearch中设置数据,并希望通过UtilityService访问TransferComponent中的数据.

I have 2 components: 1) SearchComponent 2) TransferComponent I am setting the data in SearchComponent and want to access the data in TransferComponent through utilityService.

公用服务:

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

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

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

我确定出了点问题,但这只是我无法弄清楚.对您的帮助表示感谢.

I am sure something is wrong, but it's just that I am not able to figure it out.Any help is appreciated.

推荐答案

camaron是正确的.您的错误是您两次声明UtilityService :

camaron is right. Your mistake is that you declare UtilityService twice:

  1. 一次进入SearchComponent的提供者.
  2. 曾经在TransferComponent的提供者中使用.
  1. Once in the providers of SearchComponent.
  2. Once in the providers of TransferComponent.

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

You should declare the service ONLY ONCE to make sure both components get the same instance. For this you can choose between either of these options:

  1. 声明中同时包含SearchComponentTransferComponent@NgModule提供者中声明服务. 10次​​中有9次是正确的解决方案!
  2. @Component的提供者中声明服务,该提供者是SearchComponentTransferComponent 父级.这可能不可行,具体取决于组件树的外观.
  1. Declare the service in the providers of a @NgModule which has both SearchComponent and TransferComponent in its declarations. 9 times out of 10 this is the right solution!
  2. Declare the service in the providers of a @Component which is a parent of both SearchComponent and TransferComponent. This might not be feasible depending how your component tree looks.

在选项#1之后,您最终得到:

Following option #1, you end up with:

@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注入到组件的构造函数中,而无需在组件的提供者中拒绝它:

Then inject UtilityService in your components' constructors WITHOUT REDECLARING IT in the components's providers:

@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) { }
}

这篇关于使用Angular2中的服务在组件之间共享数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆