簡體   English   中英

如何在 angular 的兄弟組件之間共享數據?

[英]How do I share data between sibling components in angular?

我有一個帶有 3 個兄弟組件的 Angular 應用程序,它們能夠訪問和更新變量“數據”。 它們連接到路由器,但我想傳遞的數據是敏感的(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 }}

看起來您希望重定向到這些組件,您可以做的是在組件一上有一個事件發射器,單擊時會將數據發送到父級(所有 3 個)。 然后在父級中,您將捕獲發射,並將其分配給您傳遞給其他組件的數據。

組件 1

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 和組件 3

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

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

家長

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

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

父.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;
    }
}

組件 1

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 和組件 3

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 ]
})

由於您要求在兄弟組件之間共享數據,我們可以通過在服務中使用BehaviourSubject來實現。

BehaviorSubject 持有需要與其他組件共享的值。 這些組件訂閱數據,簡單地返回 BehaviorSubject 值,而沒有更改該值的功能。

服務.ts

import { Observable, BehaviorSubject } from 'rxjs';

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

 constructor() { }

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

組件1.ts

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

export class component1 implements OnInit {

data: any;

constructor (private service: Service) {}

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

組件2.ts

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

export class component2 implements OnInit {

constructor ( private service: Service ) { }

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

由於您有多個接收器components ,最好的方法是使用單例共享service 因為以后如果你創建更多的接收器components ,發射到每個單獨的component是不合適的。

如果您需要:

OutputEventEmitter簡單解釋

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

Angular 可以通過$emit, $broadcast and $on在 angular 的$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

});

另外,你可以按照這個這個

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM