action-mediator
v1.0.0
Published
跨组件通信方案
Downloads
6
Readme
actionMediator ——跨组件通信方案
是什么
当前的业务架构,无法解决跨组件间的状态同步。actionMediator 能够更优雅地处理跨组件的方法调用。
场景:
账号详情页和账号列表页,渲染数据源不一样,当详情页编辑后,需要更新列表页; 虽然详情页可以调用获取列表数据的方法,但是无法获取到当前列表页分页参数和查询条件, 此时仍需由列表页保持当前查询条件调用相应接口。
世界观
actionMediator 的世界里,只有两种角色,一个是 Mediator 中介者,另一个是 Colleague 成员。
- Colleague:组件实例的描述,包括组件的实例,组件公开的方法。以成员名作为唯一标志,成员名默认是这个组件的名称,也支持自定义
- Mediator:用于管理成员间的消息传递。Colleague 注册后,Mediator 能够获得这个成员的信息,当需要调用某个 Colleague 的方法时,可以通知 Mediator 去找到对应的 Colleague
使用方法
- @colleague(colleagueName) : 注册为成员,参数 colleagueName 是必选的成员名
- @@colleagueAction(actionName): 声明公开的方法,actionName 是方法标志
- @notifyMediator(colleagueName, actionName): 通知中介,让名为 colleagueName 的成员执行 actionName 这一公开的方法
举个例子:
@colleague('AccountManageTab')
class AccountManageTab extends React.Component<PropsTypes> {
...
@colleagueAction('updateAccountList')
searchAccounts(params?: AccountManageModel.AccountQueryParam) {
this.queryParam = {...this.queryParam, ...params};
AccountManageState.fetchAccountPagingList(this.queryParam);
}
...
}
@colleague()
class AccountInfo extends React.Component<PropsTypes> {
@notifyMediator('AccountManageTab', 'updateAccountList')
addAccount(newAccount: AccountManageModel.Account) {
return AccountManageState.fetchAccountAdd(newAccount)
}
}
效果:当 AccountInfo 增加完账号时,AccountManageTab 会执行 searchAccounts,更新账号列表
原理
@colleague:生成以该组件为父类一个新的 class,重写了 constructor,当组件实例化时可以获取到该组件的实例,同时对原型链上方法进行过滤,获取到标志了 action 这一元数据的方法及其内容
@colleagueAction: 对公开的方法进行标注,增加了 action 这一元数据,内容为 actionName 和函数体
@notifyMediator:重写了原本的方法,在执行原本的方法后,通知中介找到对应的成员,让他执行对应的方法
mediator:在闭包内成为唯一的一个中介者,进行消息的转达
Q&A
- Q: 如何在异步执行后通知中介者 A: notifyMediator 会检查原先方法的返回值,如果返回 promise,则会在返回值上进行 then 调用
依赖
reflect-metadata:对公开的方法打上元数据标识
开发中遇到的坑
- 方法装饰器在类装饰器前执行,导致处理公开方法时,还没有相应的成员生成,因此使用了 reflect-metadata 对其标识,再在重写构造函数时遍历获取
更新记录
- 3.20: colleague 名称改为必传参数,因打包后 class 名会发生变化,因此使用 constructot.name 是不安全的