如何以角度在兄弟组件之间共享数据?
Posted
技术标签:
【中文标题】如何以角度在兄弟组件之间共享数据?【英文标题】:How do I share data between sibling components in angular? 【发布时间】:2017-10-11 22:16:38 【问题描述】:我有一个带有 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
【问题讨论】:
【参考方案1】:由于您要求在同级组件之间共享数据,我们可以通过在服务中使用 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);
);
【讨论】:
你忘了@Injectable
?【参考方案2】:
看起来您正在寻找重定向到这些组件,您可以做的是在组件 1 上设置一个事件发射器,单击时会将数据发送到父组件(所有 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 ]
)
【讨论】:
谢谢@Joo,我正在实施您的优雅解决方案,如果可行,会通知您。 @Joo 保存在共享服务中的数据会在使用点击浏览器刷新按钮时被删除,我们该如何处理??【参考方案3】:Angular 可以在 Angular 的 $scope
和 $rootScope
事件系统中通过 $emit, $broadcast and $on
在兄弟之间共享数据。
<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
);
另外,您可以关注this 和this
【讨论】:
对不起 eigenharsha,我很欣赏这个答案,但这是 Angular 而不是 AngularJS【参考方案4】:由于您有多个接收者components
,最好的方法是使用singleton 共享service
。因为稍后如果您创建更多接收器components
,则向每个人发送component
是不合适的。
如果你需要:
Output
和EventEmitter
的简单解释
https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html
【讨论】:
以上是关于如何以角度在兄弟组件之间共享数据?的主要内容,如果未能解决你的问题,请参考以下文章