HarmonyOS鸿蒙Next中为什么IDataSource里的listener是个数组,这么设计的目的是什么

HarmonyOS鸿蒙Next中为什么IDataSource里的listener是个数组,这么设计的目的是什么

registerDataChangeListener(listener: DataChangeListener): void {
  if (this.listeners.indexOf(listener) < 0) {
    this.listeners.push(listener);
  }
}

unregisterDataChangeListener(listener: DataChangeListener): void {
  const pos = this.listeners.indexOf(listener);
  if (pos >= 0) {
    this.listeners.splice(pos, 1);
  }
}

这是官方给的demo 对于dataSource的控制返回一个listener就够了 为什么要这么设计

我测试发现registerDataChangeListener也只是执行一次 并不会返回多次listener

unregisterDataChangeListener什么时候会触法 也没遇到过


更多关于HarmonyOS鸿蒙Next中为什么IDataSource里的listener是个数组,这么设计的目的是什么的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

【背景知识】

LazyForEach从数据源中按需迭代数据,并在每次迭代时创建相应组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会销毁并回收组件以降低内存占用。

【解决方案】

IDataSource接口的实现对象,用于管理LazyForEach的数据及相应的Listener监听器,并及时通知LazyForEach数据进行更新。 其中registerDataChangeListener是IDataSource中的方法,用于进行监听器对象的创建,而unregisterDataChangeListener则是用来注销数据改变的监听器。

/**
 * Register data change listener.
 *
 * @param { DataChangeListener } listener
 * @syscap SystemCapability.ArkUI.ArkUI.Full
 * @crossplatform
 * @atomicservice
 * @since 11
 */
registerDataChangeListener(listener: DataChangeListener): void;
/**
 * Unregister data change listener.
 *
 * @param { DataChangeListener } listener
 * @syscap SystemCapability.ArkUI.ArkUI.Full
 * @crossplatform
 * @atomicservice
 * @since 11
 */
unregisterDataChangeListener(listener: DataChangeListener): void;

这两个方案随着数据源的创建而实现,一般都都是为框架侧调用。当数据源更新时,系统就会通过registerDataChangeListener注册好的监听器回调通知UI进行数据更新。 fb84ca7f-cc8a-477d-b1d7-d46fe75a96e5.png 而为了精确的追踪到数据的变化并做到及时响应,所以为每个数据都注册了相应的Listener监听,这样就可以快速响应数据的变化,及时通知UI进行更新,避免了不必要的全局更新。

【总结】

这种为每个数据设计的监听器,具备以下优点: 1.精确追踪:系统能知道哪些数据被修改从而产生变化。 2.及时更新:当数据变化时,能及时精准的更新。

更多关于HarmonyOS鸿蒙Next中为什么IDataSource里的listener是个数组,这么设计的目的是什么的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


着不很明显吗,数据是数组,要控制单个数据都更新,删除,也得是单个区刷新

IDataSource中的listener设计为数组是为了支持多监听器。在鸿蒙Next的分布式数据管理框架中,一个数据源的变化可能需要通知多个不同的UI组件或业务模块。数组结构允许同时注册多个监听器对象,当数据发生变更时,可以遍历数组并逐一回调所有监听器,确保依赖该数据源的各个部分都能及时响应更新,实现数据与UI的高效同步。

在HarmonyOS Next中,IDataSource的监听器设计为数组(或列表)是为了支持多监听器模式。这是一个典型且必要的设计模式,其核心目的和优势如下:

  1. 解耦与灵活性:数据源(DataSource)可能被多个独立的UI组件或业务模块同时观察。例如,同一个列表数据的变化,可能需要同时刷新当前页面、更新底部统计栏、并向服务器同步。使用数组存储多个监听器,允许这些观察者独立注册和注销,互不影响,实现了高度的解耦。

  2. 一对多通信:这是设计为数组最直接的原因。IDataSource作为被观察者(Subject),当底层数据发生变化(如数据加载、插入、删除、更新)时,需要有能力通知所有关心此变化的监听器。通过遍历listeners数组并逐一调用其回调方法(如onDataReloaded, onDataAdd等),可以高效地实现一对多的广播式通知。

  3. 动态管理监听生命周期:不同的组件有其自身的生命周期。registerDataChangeListenerunregisterDataChangeListener提供了标准的订阅与取消订阅机制。例如,当一个List组件被创建时注册监听,在页面销毁或组件隐藏时注销监听,可以避免内存泄漏和无效的回调调用。数组结构使得增删监听器的操作非常高效和清晰。

针对您的具体观察:

  • “registerDataChangeListener也只是执行一次”:这是正确的。每个监听器(通常是一个对象或函数)在自身生命周期内通常只注册一次。数组的作用是累积来自不同地方的多个这样的“一次注册”。
  • “unregisterDataChangeListener什么时候会触发”:通常在观察者(如UI组件)被销毁或不再需要监听数据变化时调用。例如,在ArkUI的aboutToDisappear生命周期或组件卸载时,应调用此方法移除对应的监听器,这是防止内存泄漏的关键步骤。

总结:listener设计为数组,是遵循观察者模式的经典实现。它确保了IDataSource具备向多个消费者广播数据变更的能力,同时支持监听器的安全动态管理,这是构建响应式、松耦合UI系统的基石。在您的开发中,如果一个数据源确实只需要通知一个监听器,那么数组中通常也只包含一个元素,但框架设计必须为更普遍的复杂场景提供支持。

回到顶部