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

查看:28
本文介绍了使用 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我在SearchComponent中设置数据,想通过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. @NgModule 的提供者中声明服务,在其声明中同时具有 SearchComponentTransferComponent.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天全站免登陆