应用场景

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

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

应用举例

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

引发事件

1. 声明事件

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

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

2. 引发事件

a-base-sync/backend/src/controller/auth.js

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

响应事件

1. 声明事件实现

test-party/backend/src/meta.js

event: {
  implementations: {
    'a-base:loginInfo': 'test/event/loginInfo',
  },
名称 说明
a-base:loginInfo 模块名称:事件名称
test/event/loginInfo 响应事件的后端Api路由

2. 定义后端Api路由

test-party/backend/src/routes.js

{ method: 'post', path: 'test/event/loginInfo', controller: testEventUserVerify, middlewares: 'test', meta: { auth: { enable: false } } },

3. 控制器方法

在本示例中,响应事件a-base:loginInfo,判断当前用户的登录方式,如果是通过Github登录的,那么就修改模块a-layoutmobile的前端参数,从而修改Mobile场景下的页面布局

test-party/backend/src/controller/test/event/userVerify.js

async loginInfo() {
  // change the config of mobile layout by checking the user's login status
  const data = this.ctx.request.body.data;
  const info = data.info;
  const provider = info.user && info.user.provider;
  if (provider && provider.module === 'a-authgithub' && provider.providerName === 'authgithub') {
    info.config = extend(true, info.config, {
      modules: {
        'a-layoutmobile': {
          layout: {
            login: '/a/login/login',
            loginOnStart: true,
            toolbar: {
              tabbar: true, labels: true, bottomMd: true,
            },
            tabs: [
              { name: 'Mine', tabLinkActive: true, iconMaterial: 'person', url: '/a/user/user/mine' },
            ],
          },
        },
      },
    });
  }
  this.ctx.success();
}