Angular2 - 使用服务的组件之间的交互
Angular2 - Interaction between components using a service
我有两个组件 A 和 B,其中组件 A 包含一个按钮。我希望当用户点击这个按钮时,在组件 B
上触发一个函数
<A></A>
<router-outlet></router-outlet>
并且组件 B 是使用 routing.I 呈现的,我正在考虑使用具有可观察布尔值的服务,该值指示 A 中的按钮是否被单击。这是实现它的正确方法吗?
Angular 服务
您必须使用服务在您的两个组件之间进行通信。
见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
您的服务有一个 属性 事件。所以组件 A 可以发出事件,组件 B 可以订阅它。
使用 RxJS 发出和订阅您的事件。
If my answer does not satisfy you. Please tell me and I will work on
it.
共享服务是 non-related 组件之间的一种常见通信方式。
您的组件需要 ,因此请确保它在根级别提供。
使用 的示例:
共享服务:
@Injectable()
export class SharedService {
isVisibleSource: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() { }
}
组件 1:
export class Component1 {
isVisible = 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(): void {
this.sharedService.isVisibleSource.subscribe((isVisible) => {
console.log('isVisible: ', isVisible); // => true/false
});
}
}
值得一提的是,BehaviorSubject
在订阅后 returns 它持有的最后一个值,因此上例中的组件将在实例化后立即更新为最新值。
BehaviorSubject
甚至无需订阅它也可以获取其最新值:
this.sharedService.isVisibleSource.getValue(); // => true/false
停止使用组件交互服务!!!
服务在编程中是一个无状态的概念,它只能依靠输入和其他注入的服务来产生它的输出。在服务中存储数据(尽管有效)是反模式(因为您的服务现在是有状态的)。
您可以通过绑定组件的@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 得到了强烈强调(而使用服务方法则不会)。
我知道组件通信的共享服务没有上述方法那么复杂,但仅仅因为它有效并不意味着您应该这样做。如果您的梅赛德斯被锁在门外,您更愿意做什么:打破 window 玻璃并打开门锁,或者叫锁匠过来打开它。
p.s。 Angular 是涂料因此比喻(梅赛德斯)
我有两个组件 A 和 B,其中组件 A 包含一个按钮。我希望当用户点击这个按钮时,在组件 B
上触发一个函数<A></A>
<router-outlet></router-outlet>
并且组件 B 是使用 routing.I 呈现的,我正在考虑使用具有可观察布尔值的服务,该值指示 A 中的按钮是否被单击。这是实现它的正确方法吗?
Angular 服务
您必须使用服务在您的两个组件之间进行通信。
见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
您的服务有一个 属性 事件。所以组件 A 可以发出事件,组件 B 可以订阅它。
使用 RxJS 发出和订阅您的事件。
If my answer does not satisfy you. Please tell me and I will work on it.
共享服务是 non-related 组件之间的一种常见通信方式。
您的组件需要
使用
共享服务:
@Injectable()
export class SharedService {
isVisibleSource: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() { }
}
组件 1:
export class Component1 {
isVisible = 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(): void {
this.sharedService.isVisibleSource.subscribe((isVisible) => {
console.log('isVisible: ', isVisible); // => true/false
});
}
}
值得一提的是,BehaviorSubject
在订阅后 returns 它持有的最后一个值,因此上例中的组件将在实例化后立即更新为最新值。
BehaviorSubject
甚至无需订阅它也可以获取其最新值:
this.sharedService.isVisibleSource.getValue(); // => true/false
停止使用组件交互服务!!!
服务在编程中是一个无状态的概念,它只能依靠输入和其他注入的服务来产生它的输出。在服务中存储数据(尽管有效)是反模式(因为您的服务现在是有状态的)。
您可以通过绑定组件的@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 得到了强烈强调(而使用服务方法则不会)。
我知道组件通信的共享服务没有上述方法那么复杂,但仅仅因为它有效并不意味着您应该这样做。如果您的梅赛德斯被锁在门外,您更愿意做什么:打破 window 玻璃并打开门锁,或者叫锁匠过来打开它。
p.s。 Angular 是涂料因此比喻(梅赛德斯)