Angular2 - 使用服务的组件之间的交互

时间:2017-01-31 13:27:47

标签: angular typescript angular2-routing angular2-services

我有两个组件A和B,其中组件A包含一个按钮。我希望当用户点击此按钮时,在组件B上激活一个功能

<A></A>
<router-outlet></router-outlet>

组件B使用routing进行渲染。我正在考虑使用带有可观察布尔值的服务,该服务指示是否单击了A中的按钮。这是实现它的正确方法吗?

3 个答案:

答案 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)

Angular Service

您必须使用服务在两个组件之间进行通信。

请参阅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。角度很浓,因此类推(奔驰)