[英]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
是不合適的。
如果您需要:
Output
和EventEmitter
簡單解釋
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.