应用场景

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

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

应用举例

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

事件提供者

- 声明事件

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

  1. 1event: {
  2. 2 declarations: {
  3. 3 loginInfo: 'Login Info',
  4. 4 },
  5. 5},
名称 说明
loginInfo 事件名称
Login Info 事件说明

- 引发事件

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

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

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

事件消费者

- 声明事件实现

test-party/backend/src/meta.js

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

- 定义Bean组件

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

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

  1. 1const require3 = require('require3');
  2. 2const extend = require3('extend2');
  3. 3
  4. 4module.exports = ctx => {
  5. 5 // const moduleInfo = ctx.app.meta.mockUtil.parseInfoFromPackage(__dirname);
  6. 6 class eventBean {
  7. 7
  8. 8 async execute(context, next) {
  9. 9 const data = context.data;
  10. 10 const info = data.info;
  11. 11 info.config = extend(true, info.config, {
  12. 12 modules: {
  13. 13 'a-dashboard': {
  14. 14 dashboard: {
  15. 15 presets: {
  16. 16 anonymous: {
  17. 17 home: 'test-party:dashboardTest',
  18. 18 },
  19. 19 authenticated: {
  20. 20 home: 'test-party:dashboardTest',
  21. 21 },
  22. 22 },
  23. 23 },
  24. 24 },
  25. 25 },
  26. 26 });
  27. 27 // next
  28. 28 await next();
  29. 29 }
  30. 30
  31. 31 }
  32. 32
  33. 33 return eventBean;
  34. 34};
名称 说明
context.data 外部传入的参数
next event采用洋葱圈模型,调用next从而允许其他事件实现的执行

- 注册Bean组件

src/suite-vendor/test-party/modules/test-party/backend/src/beans.js

  1. 1const eventLoginInfoDashboard = require('./bean/event.loginInfoDashboard.js');
  2. 2
  3. 3module.exports = app => {
  4. 4 const beans = {
  5. 5 // event
  6. 6 'event.loginInfoDashboard': {
  7. 7 mode: 'ctx',
  8. 8 bean: eventLoginInfoDashboard,
  9. 9 },
  10. 10 };
  11. 11 return beans;
  12. 12};
注册名称 场景 所属模块 global beanFullName
loginInfoDashboard event test-party false test-party.event.loginInfoDashboard