1.0.0 • Published 5 years ago

action-mediator v1.0.0

Weekly downloads
6
License
ISC
Repository
github
Last release
5 years ago

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 是不安全的