【HarmonyOS Next】跨模块交互的事件路由

  • 本文所有代码案例均基于Api12。

如果一个工程中,已经使用分模块开发,多个项目要耦合到一起,难免会遇到跨模块的方法调用。在业务层,仓库A直接调用仓库B,就构成了引用,想避免引用就需要一个中间库帮他们传递消息。

AB双方约定好消息路由,分实现、注册、调用,三步实现通信。

1、创建事件路由名和实现对象: 创建实现对象,在指定方法内实现路由方法

typescript 复制代码
// 路由地址,根据需要命名
let testRouter: CustomURL.Key = new CustomURL.Key("test_path")

// 路由方法实现对象,需要继承自CustomEventRouter.Protocol 
export class TestEventRouter implements CustomEventRouter.Protocol {

  registerRouter(navigator: CustomEventRouter.Navigator): void {

    navigator.handleEvent(testRouter, (params: Record<string, Object>) => {
      // xxxxxxx
      return undefined
    })

  }
}

2、注册: APP启动后将路由对象注册给事件路由

scss 复制代码
  // 不同模块下的实现对象可以分别注入
  CustomEventRouter.registerModule(new TestEventRouter(), new Test1EventRouter())
  CustomEventRouter.registerModule(new Test2EventRouter())

3、调用: 根据路由名调用方法并获取返回参数

javascript 复制代码
  // 根据实际需要接收返回值,如果没有设置返回值,可以不接收
  let result: Object = CustomEventRouter.open(testRouter)

这样一个事件路由就做好了。


事件路由的核心代码:

typescript 复制代码
/**
 * 路由地址的声明。起到代码约束功能
 */
export namespace CustomURL {
  /**
   * 路由地址的数据类型,约束业务模块调用规范
   */
  export class Key {
    // 真实的路由地址
    path: string

    constructor(path: string) {
      this.path = path
    }
  }
}

export namespace CustomEventRouter {

  /**
   * 调用打开路由
   * @param url 路由地址
   * @param paramter 参数
   * @returns 路由实现方法的回调
   */
  export function open(
    url: CustomURL.Key,
    paramter?: Object
  ): ESObject {
    if (baseNavigator.has(url.path)) {
      let objFunc: Function | undefined = baseNavigator.get(url.path)
      if (objFunc) {
        return objFunc(paramter)
      }
    }
  }

  /**
   * 注册路由实现对象的方法,每个模块需自己实现Protocol接口,app启动后在适当的时机调用该方法实现注册,如Index.ets文件
   * @param items 实现路由注册接口的对象
   */
  export function registerModule(...items: Protocol[]) {
    let navigator: Navigator = new Navigator()
    items.forEach((item: Protocol, index: number, array: Protocol[]) => {
      item.registerRouter(navigator)
    })
  }

  /**
   * 移除指定路由
   * @param items 要移除的路由URL
   */
  export function removeURL(...items: CustomURL.Key[]) {
    items.forEach((url: CustomURL.Key, index: number, array: CustomURL.Key[]) => {
      baseNavigator.delete(url.path)
    })
  }

  /**
   * 需要业务组件去实现的路由接口。用协议实现对其他模块方法的调用
   */
  export interface Protocol {
    /**
     * 在这个方法中注册路由
     * @param navigator 注册的规范对象
     */
    registerRouter(navigator: Navigator): void
  }

  /**
   * RouteNavigator是用来注册的model,对代码规范约束的功能。不对外直接暴露baseNavigator,是避免map类型被错误操作
   */
  export class Navigator {
    /**
     * 调用这个方法实现注册单条路由
     * @param key 路由地址
     * @param value 实现方法,Function跟系统用法相同
     */
    handleEvent(key: CustomURL.Key, value: Function) {
      baseNavigator[key.path] = value
    }
  }

  /**
   * 实际存储路由和方法的对象。因为是map,不对外部文件暴露,避免错误操作
   */
  const baseNavigator: Map<string, Function> = new Map()
}
  • 关于本文中使用到【ESObject】的说明: 在鸿蒙当前的版本中,已经不允许直接使用any类型操作对象,检查规则会报错。官方文档给了说明,他们统计过必须使用any的代码不到1%,如果特殊场景下,也给出了替代方案: declare type ESObject = any; 在本文中,因为需要和Function对齐传参,所以使用了替代方案声明参数。
相关推荐
轻口味1 小时前
【每日学点HarmonyOS Next知识】多继承、swiper容器、事件传递、滚动安全区域、提前加载网络图片
华为·harmonyos·harmonyosnext
别说我什么都不会1 小时前
鸿蒙轻内核M核源码分析系列二一 05 文件系统FatFS
操作系统·嵌入式·harmonyos
Georgewu2 小时前
【HarmonyOS Next】鸿蒙应用故障处理思路详解
前端·vue.js·harmonyos
盖世栗子2 小时前
HarmonyOS中Image组件的缩放模式
harmonyos
幽蓝计划6 小时前
HarmonyOS Next开发教程之地图定位
harmonyos
轻口味10 小时前
【每日学点HarmonyOS Next知识】Web交互、列表拖拽、横屏后布局、Event序列问题、Scroll与Web组合
前端·交互·harmonyos·harmonyosnext
轻口味20 小时前
【每日学点HarmonyOS Next知识】截图组件截取列表、Toggle组件、Web组件请求头、列表选择弹窗、游戏加速
前端·游戏·harmonyos·harmonyosnext
鸿蒙开发工程师—阿辉20 小时前
HarmonyOS Next元服务网络请求封装实践
网络·华为·typescript·harmonyos·元服务
__Benco1 天前
OpenHarmony 5.0.0 Release
harmonyos