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

mrs*_*n22 17 angular2-routing angular2-components angular

我正在使用angular2开发一个应用程序.我有一个场景,我需要在路由时使用复杂数据(对象数组)从一个组件传递到另一个组件(它们不是父子,它们是两个独立的组件)(使用router.navigate()).我用Google搜索了这一点,大部分结果都描述了父子组件的场景.我已经完成了结果并找到了传递数据的方法.

1)创建共享服务2)作为路由参数传递

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

更新:我在我的场景中添加了一些代码.请让我知道为什么通过共享服务传递数据不起作用的错误.

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

公用事业服务

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
    }



}
Run Code Online (Sandbox Code Playgroud)

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']);

    }
}
Run Code Online (Sandbox Code Playgroud)

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());
}
}
Run Code Online (Sandbox Code Playgroud)

我确信有些事情是错的,但这只是我无法弄明白.任何帮助都表示赞赏.

Ang*_*hef 24

卡马龙是对的.你的错误是你宣布了UtilityService两次:

  1. 一旦进入供应商SearchComponent.
  2. 一旦进入供应商TransferComponent.

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

  1. 在一个提供商声明服务@NgModule既有SearchComponentTransferComponent在它的声明.10次​​中有9次这是正确的解决方案!
  2. 声明中的提供者的服务@Component这是一个双方的父母SearchComponentTransferComponent.根据组件树的外观,这可能不可行.

在选项#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 { }
Run Code Online (Sandbox Code Playgroud)

然后注入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) { }
}
Run Code Online (Sandbox Code Playgroud)