我有一个包含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 }}
答案 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
发送不适合。
如果你需要:
Output
和EventEmitter
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
});
答案 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);
});
}