Angular9 公共组件封装之三级组件通信
RT
一、需求
- 白色区域为公共组件A;
- 红色区域为公共组件B,有色绿色区域为多个功能按钮(如年、月、日)
- 黑色区域为组件C(可以看做是一个页面)
- 组件C用于想服务端拉取数据,再向组件B传递,并且在页面中复用组件B(多次)
- 组件A用于展示数据
- 组件B中的绿色按钮部分用于触发重新拉取数据
二、我的解决方案
- 使用@Input和@Output逐层通信,C拉取数据传递给A,B触发点击事件后通过
EventEmitter
传递给A,在A中再通过EventEmitter
传递给C,C接收后再向服务端拉取数据,再把获取的数据传递给A,用作展示 - 新建一个
service
,在service
中定义一个subject
,再定义两个方法sendMsg
和getMsg
用于发布订阅,在C中注入service
,调用getMsg
方法用于订阅消息,在A中注入service
,调用sendMsg
方法用于发布消息
三、思考
- 第一种解决方案,个人觉得这样不够友好,且传递次数过多,而且写法也比较low
- 第二种解决方案,使用
rxjs
,感觉高大上了很多,但不易阅读。并且当在C组件多次复用A的时候,依然要使用第一种解决方案去向每一个复用的A组件传递一个唯一标识name
,然后A再将name
传递给B,当B触发点击事件的时候再把这个唯一标识name
传递回C,用于确定再次获取数据后给哪个被复用的A更新数据。这样就很绕
四、问题
- 有没有其他解决方案?
- 如果没有,在原有的解决方案中如何能更优雅?
回答
既然已经写成组件了,angular 就只有@input和@output来传递信息了。
多级组件双向通讯一般用service,如果只是共享数据,直接用service的属性就可以,如果需要互相通知,可以用subject,这是标准的做法。
@input和@output是父子组件通讯的基本机制,但层数多了就不好用了。
service还可以实现同级组件之间通讯,甚至没有什么关系的组件之间的通讯。
子组件可以直接依赖注入其上级的组件
<component-a> <component-b></component-b>
</component-a>
export class ComponentB { constructor(private componentA: ComponentA) {
}
}
自上而下的数据管理方式避免不了这种一级一级的消息传递。解决方案就是类似 redux 的这种统一的中心式状态管理方案。
题目中的问题根源在于只有最顶层的 C 有资格去服务器拉数据,所以动作要一层层冒上去,然后再更新数据,再把数据一层层分发下来。
中心式的状态管理的思想是,把动作和数据抽离到一个中心去管理,动作会改变数据,数据改变后会通知订阅者。各组件大家无论层级高低,都可以订阅自己感兴趣的数据,都可以触发恰当的动作。
所以简单的实现,你可以用一个 service 来抽象这个状态管理器,配合 rxjs 不难实现。
项目很大层级很深的,可以考虑 ngrx ,基本就是 redux + rxjs,配合 Angular 的依赖注入,个人感觉比 react + redux 还好用一些。
以上是 Angular9 公共组件封装之三级组件通信 的全部内容, 来源链接: utcz.com/a/41642.html