# Angular 父组件与子组件通讯之共享服务

> 父组件和它的子组件共享同一个服务，利用该服务在组件家族内部实现双向通讯。该服务实例的作用域被限制在父组件和其子组件内。这个组件子树之外的组件将无法访问该服务或者与它们通讯。

Author: DeathGhost
Published: 2019-06-28 22:32:36
Category: angular
Canonical: https://www.deathghost.cn/article/angular/50
Keywords: angular, EventEmitter, 通讯, 通信, 交互, 服务, 共享服务, 父子组件, 数据传输, 双向通信

[angular](https://www.deathghost.cn/catalog/angular)有多种组件间传值通讯方法，今天在这里引用官方笔记下通过服务进行父子组件之间的通讯。具体根据项目内容归属对其划分。

前提是在哪个模块使用就在哪里引入，如果是全局性的，直接导入在项目的根模块即可，其下的组件均可访问该服务或通讯。

![angular通讯](https://www.deathghost.cn/public/upload/article/2019/06/1561733304805.jpg)

Angular EventEmitter 服务通讯

使用场景：非同一个模块结构布局中某一路由下的页面在某种情况下需要向外发送命令，让其收到命令进行执行的情况下我们可以在根模块下创建一个服务，让其子组件均可访问。

好比父组件含有导航列表，我们在子组件中管理功能导航保存完毕后通知父组件导航更新一般，发送指定标识，其接收到对其再次请求。

首先在根模块下创建一个服务。

import { Injectable, EventEmitter } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class EventEmitterService {
  public eventEmit =  new EventEmitter();
  constructor() {}
}
第二步在根模块将其导入。（e.g:app.module）

import { EventEmitterService } from './service/event-emitter.service';
...
// 将其共享给子组件
providers: [...srevice]
...
最后子组件通过构造函数将其注入进来。

import { EventEmitterService } from './service/event-emitter.service';
...
constructor(private emitService: EventEmitterService){}
...
使用方法：

发送：

// 例如
this.emitService.eventEmit.emit({isClosed: true, params: 0});
接收：

import { Subscription } from 'rxjs';
...
getVal = '';
subscription: Subscription;
...?
this.subscription = this.emitS.eventEmit.subscribe(data => {
  if (data['isClosed']) {
   this.getVal = data['params'];
  }
});
另外，自己订阅在组件被销毁时需要调用unsubscribe()退订，防止内存泄漏。不然你会看到意想不到的效果，即使您导航到另一个组件视图里，也会一直有效，直到取消订阅为止。

所以，还需要再接收一方的组件ngOnDestroy钩子里执行退订。

// ? 退订
this.subscription.unsubscribe();
如同 上篇文章"[Angular 路由快照](https://www.deathghost.cn/article/angular/28)"场景下，如果使用到此方法通讯，不退订就会出现这种情况。具体细节根据实际项目而定，仅供阅读参考。

## Related

- Previous: [通过 angular CDK 实现页面元素拖放](https://www.deathghost.cn/article/angular/46)
- Next: [Angular自定义预加载策略](https://www.deathghost.cn/article/angular/88)
