应用场景

在实际业务开发当中,为了进一步增强灵活性和可扩展性,提供了后端事件的特性。我们可以考虑如下应用场景:

  1. 当页面初始化时,前端会调用后端Api接口/a/base/auth/echo,返回当前用户的信息。如果没有登录,就会自动打开登录页面
  2. 由于这是由模块a-base提供的系统架构,如果其他业务模块也想在这个后端Api接口返回的用户信息中追加数据,该如何实现呢?

应用举例

仍以上面的应用场景为例,分析一下模块a-base如何引发事件,其他模块如何响应事件

事件提供者

- 声明事件

a-base-sync/backend/src/meta.js

event: {
  declarations: {
    loginInfo: 'Login Info',
  },
},
名称 说明
loginInfo 事件名称
Login Info 事件说明

- 引发事件

模块a-event提供了全局Bean组件event,可以直接通过ctx.bean.event引发事件

src/module-system/a-base-sync/backend/src/bean/bean.auth.js

async getLoginInfo() {
  const config = await this._getConfig();
  const info = {
    user: ctx.state.user,
    instance: this._getInstance(),
    config,
  };
  // login info event
  await ctx.bean.event.invoke({
    name: 'loginInfo', data: { info },
  });
  return info;
}
名称 说明
module 事件所属模块名称,如果没有指定,默认为当前模块
name 事件名称
data 事件的自定义数据

事件消费者

- 声明事件实现

test-party/backend/src/meta.js

event: {
  implementations: {
    'a-base:loginInfo': 'loginInfoDashboard',
  },
名称 说明
a-base:loginInfo 模块名称:事件名称
loginInfoDashboard 响应事件的Bean组件

- 定义Bean组件

在本示例中,响应事件a-base:loginInfo,修改home仪表板对应的配置(原子的atomStaticKey)

src/module-vendor/test-party/backend/src/bean/event.loginInfoDashboard.js

const require3 = require('require3');
const extend = require3('extend2');

module.exports = ctx => {
  // const moduleInfo = ctx.app.meta.mockUtil.parseInfoFromPackage(__dirname);
  class eventBean {

    async execute(context, next) {
      const data = context.data;
      const info = data.info;
      info.config = extend(true, info.config, {
        modules: {
          'a-dashboard': {
            dashboard: {
              presets: {
                anonymous: {
                  home: 'test-party:dashboardTest',
                },
                authenticated: {
                  home: 'test-party:dashboardTest',
                },
              },
            },
          },
        },
      });
      // next
      await next();
    }

  }

  return eventBean;
};
名称 说明
context.data 外部传入的参数
next event采用洋葱圈模型,调用next从而允许其他事件实现的执行

- 注册Bean组件

src/module-vendor/test-party/backend/src/beans.js

const eventLoginInfoDashboard = require('./bean/event.loginInfoDashboard.js');

module.exports = app => {
  const beans = {
    // event
    'event.loginInfoDashboard': {
      mode: 'ctx',
      bean: eventLoginInfoDashboard,
    },
  };
  return beans;
};
注册名称 场景 所属模块 global beanFullName
loginInfoDashboard event test-party false test-party.event.loginInfoDashboard