如何以角度分享兄弟组件之间的数据?

时间:2017-05-12 14:35:10

标签: angular

我有一个包含3个兄弟组件的Angular应用程序,他们能够访问和更新变量" data"。它们连接到路由器,但我想传递的数据是敏感的(api端点确定折扣)所以我不能使用cmp2 /:data

组件1有一个名为data的对象,组件2和3需要接收这个数据对象。我认为这可以通过共享服务完成,但我不太确定如何让这个事件发射器工作..

我的index.html:

<router-outlet></router-outlet>

组件1:

<button [routerLink]=['cmp2/']>Go to Comp 2 </button>
<button [routerLink]=['cmp3/']>Go to Comp 3 </button>

组件2和3:

{{ data }}

4 个答案:

答案 0 :(得分:11)

看起来你正在寻找重定向到那些组件,你可以做的是在组件1上有一个事件发射器,点击它会将数据发送到父组件(全部3)。然后在父级中捕获emit,并将其分配给传递给其他组件的数据。

的Component1

import { Component, EventEmitter, Output } from '@angular/core';
import { Router }                          from '@angular/router';

@Component(...)
export class Component1 {
    @Output() redirect:EventEmitter<any> = new EventEmitter();

    data:any = {text: "example"};

    constructor(private router:Router){}

    changeComponent(url:string){
        this.redirect.emit(data);//emits the data to the parent
        this.router.navigate([url]);//redirects url to new component
    }
}

组件2&amp; Component3

import { Component, Input } from '@angular/core';

@Component(...)
export class Component2 {
    @Input() data:any;
}

import { Component } from '@angular/core';

@Component(...)
export class Parent {
    parentData:any;
}

Parent.html

<component1 (redirect)="parentData=$event"></component1>
<component2 [data]="parentData"></component2>
<component3 [data]="parentData"></component3>

另一个选项,如果你没有父项,就是有一个服务,你注入每个父服务器,然后接收器挂钩到OnInit生命周期钩子。这是有效的,因为如果在共享模块的提供者中,服务是单例。

服务

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

@Injectable()
export class SharingService{
    private data:any = undefined;

    setData(data:any){
        this.data = data;
    }

    getData():any{
        return this.data;
    }
}

的Component1

import { Component }      from '@angular/core';
import { Router }         from '@angular/router';
import { SharingService } form './sharing.service';

@Component(...)
export class Component1 {

    data:any = {text: "example"};

    constructor(private router:Router,
        private sharingService:SharingService){}

    changeComponent(url:string){
        this.sharingService.setData(this.data);
        this.router.navigate([url]);//redirects url to new component
    }
}

组件2&amp; Component3

import { Component, OnInit } from '@angular/core';
import { SharingService }    form './sharing.service';

@Component(...)
export class Component2 implements OnInit{
    data:any;

    constructor(private router:Router,
        private sharingService:SharingService){}

    ngOnInit(){
        this.data = this.sharingService.getData();
    }
}

确保将其添加到模块的providers数组中。

模块

import { SharingService } from './sharing.service';
...

@NgModule({
    ...
    providers: [ SharingService ]
})

答案 1 :(得分:1)

由于您有多个接收方components,最好的方法是使用单例共享service。因为稍后如果您创建了更多接收者components,则向每个人component发送不适合。

如果你需要:

OutputEventEmitter

的简单说明

https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html

答案 2 :(得分:1)

Angular可以在角度$emit, $broadcast and $on$scope事件系统中通过$rootScope在兄弟姐妹之间共享数据。

<div>
  <div ng-controller="SiblingOneCtrl1 as sib1" class="ng-scope">
    // SiblingOneCtrl
  </div>
  <div ng-controller="SiblingTwoCtrl2 as sib2" class="ng-scope">
    // SiblingTwoCtrl
  </div>
</div>
app.controller('SiblingOneCtrl1',
  function SiblingOneCtrl1 ($rootScope) {

  $rootScope.$on('rootScope:emit', function (event, data) {
    console.log(data); // 'Emit!'
  });

  $scope.$on('rootScope:broadcast', function (event, data) {
    console.log(data); // 'Broadcast!'
  });

  $rootScope.$on('rootScope:broadcast', function (event, data) {
    console.log(data); // 'Broadcast!'
  });

});

app.controller('SiblingOneCtrl2',
  function SiblingOneCtrl2($rootScope) {

  $rootScope.$emit('rootScope:emit', 'Emit!'); // $rootScope.$on
  $rootScope.$broadcast('rootScope:broadcast', 'Broadcast'); // $rootScope.$on && $scope.$on

});

另外,您可以关注thisthis

答案 3 :(得分:1)

由于您已要求在同级组件之间共享数据,我们可以通过在服务中使用 BehaviourSubject 来实现。

BehaviorSubject包含需要与其他组件共享的值。这些组件订阅数据,这些数据很容易返回BehaviorSubject值,而没有更改值的功能。

Service.ts

import { Observable, BehaviorSubject } from 'rxjs';

export class Service {
       private data = new BehaviorSubject("")
       currentData = this.data.asObservable();

 constructor() { }

 setData(data) {
      this.data.next(data);
 }

Component1.ts

import { Service } from '../service.service';

export class component1 implements OnInit {

data: any;

constructor (private service: Service) {}

sendDataToService() {
     this.service.setData(this.data);
}

Component2.ts

import { Service } from '../../service.service';

export class component2 implements OnInit {

constructor ( private service: Service ) { }

ngOnInit() {
    this.service.currentData.subscribe(data => {
      console.log(data);
    });
}