我有两个组件A和B,其中组件A包含一个按钮。我希望当用户点击此按钮时,在组件B上激活一个功能
<A></A>
<router-outlet></router-outlet>
组件B使用routing进行渲染。我正在考虑使用带有可观察布尔值的服务,该服务指示是否单击了A中的按钮。这是实现它的正确方法吗?
答案 0 :(得分:16)
共享服务是非相关组件之间通信的常用方式。 您的组件需要use a single instance of the service,因此请确保它在根级别提供。
使用BehaviorSubject as a data delegate的示例:
共享服务:
@Injectable()
export class SharedService {
isVisibleSource: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() { }
}
组件1:
export class Component1 {
isVisible: boolean = false;
constructor(private sharedService: SharedService) { }
onClick(): void {
this.isVisible = !this.isVisible;
this.sharedService.isVisibleSource.next(this.isVisible);
}
}
组件2:
export class Component2 {
constructor(private sharedService: SharedService) { }
ngOnInit() {
this.sharedService.isVisibleSource.subscribe((isVisible: boolean) => {
console.log('isVisible: ', isVisible); // => true/false
});
}
}
值得一提的是,订阅时BehaviorSubject
会返回它所持有的最后一个值,因此上述示例中的组件将在实例化后立即使用最新值进行更新。
BehaviorSubject
也允许在不订阅它的情况下获取其最新值:
this.sharedService.isVisibleSource.getValue(); // => true/false
答案 1 :(得分:1)
您必须使用服务在两个组件之间进行通信。
请参阅https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
您的服务有财产事件。因此,组件A可以发出事件,组件B可以订阅它。
使用RxJS发出和订阅您的活动。
如果我的回答不满足你。请告诉我,我会继续努力 它
答案 2 :(得分:-2)
停止使用服务进行组件交互!!!
服务是编程中的无状态概念,它只能依靠输入和其他注入的服务来产生其输出。在服务内部存储数据(尽管可行)是一种反向模式(因为您的服务现在是有状态的)。
可以通过绑定组件的@Input()和@Output()来实现所需的功能:
//main container html
<A></A>
<router-outlet (activate)="onRouterOutletActivate($event)"></router-outlet>
//main container ts
@ViewChild(ComponentA, {static: false}) a : ComponentA;
onRouterOutletActivate(event: ContainerOfB): void {
this.activeRouteComponent = event;
// make sure doStuff method is defined public in ComponentB
// clickOutput is an @Output() on ComponentA which propagates click event
this.a.clickOutput.subscribe(() => this.activeRouteComponent.b.doStuff());
}
//ContainerOfB, the container that has B in it
@ViewChild(ComponentB, {static: false}) b : ComponentB;
//ComponentA html
<button (click)="callback()">button</button>
//ComponentA ts
@Output() clickOutput: EventEmitter<void> = new EventEmitter<void>()
callback() { this.clickOutput.emit(); }
通过在Angular的核心中使用rxjs,您还将获得异步性和反应性(而使用服务方法则不会)
我了解到,用于组件通信的共享服务没有上面的方法复杂,但是仅仅因为它起作用了并不意味着您应该这样做。如果您被梅赛德斯锁在外面,您宁愿做什么:打破玻璃窗并解锁门,或者打电话给锁匠过来将其解锁。
p.s。角度很浓,因此类推(奔驰)