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
【背景知识】
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进行数据更新。
而为了精确的追踪到数据的变化并做到及时响应,所以为每个数据都注册了相应的Listener监听,这样就可以快速响应数据的变化,及时通知UI进行更新,避免了不必要的全局更新。
【总结】
这种为每个数据设计的监听器,具备以下优点: 1.精确追踪:系统能知道哪些数据被修改从而产生变化。 2.及时更新:当数据变化时,能及时精准的更新。
更多关于HarmonyOS鸿蒙Next中为什么IDataSource里的listener是个数组,这么设计的目的是什么的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
着不很明显吗,数据是数组,要控制单个数据都更新,删除,也得是单个区刷新
IDataSource中的listener设计为数组是为了支持多监听器。在鸿蒙Next的分布式数据管理框架中,一个数据源的变化可能需要通知多个不同的UI组件或业务模块。数组结构允许同时注册多个监听器对象,当数据发生变更时,可以遍历数组并逐一回调所有监听器,确保依赖该数据源的各个部分都能及时响应更新,实现数据与UI的高效同步。
在HarmonyOS Next中,IDataSource的监听器设计为数组(或列表)是为了支持多监听器模式。这是一个典型且必要的设计模式,其核心目的和优势如下:
-
解耦与灵活性:数据源(DataSource)可能被多个独立的UI组件或业务模块同时观察。例如,同一个列表数据的变化,可能需要同时刷新当前页面、更新底部统计栏、并向服务器同步。使用数组存储多个监听器,允许这些观察者独立注册和注销,互不影响,实现了高度的解耦。
-
一对多通信:这是设计为数组最直接的原因。
IDataSource作为被观察者(Subject),当底层数据发生变化(如数据加载、插入、删除、更新)时,需要有能力通知所有关心此变化的监听器。通过遍历listeners数组并逐一调用其回调方法(如onDataReloaded,onDataAdd等),可以高效地实现一对多的广播式通知。 -
动态管理监听生命周期:不同的组件有其自身的生命周期。
registerDataChangeListener和unregisterDataChangeListener提供了标准的订阅与取消订阅机制。例如,当一个List组件被创建时注册监听,在页面销毁或组件隐藏时注销监听,可以避免内存泄漏和无效的回调调用。数组结构使得增删监听器的操作非常高效和清晰。
针对您的具体观察:
- “registerDataChangeListener也只是执行一次”:这是正确的。每个监听器(通常是一个对象或函数)在自身生命周期内通常只注册一次。数组的作用是累积来自不同地方的多个这样的“一次注册”。
- “unregisterDataChangeListener什么时候会触发”:通常在观察者(如UI组件)被销毁或不再需要监听数据变化时调用。例如,在ArkUI的
aboutToDisappear生命周期或组件卸载时,应调用此方法移除对应的监听器,这是防止内存泄漏的关键步骤。
总结:
将listener设计为数组,是遵循观察者模式的经典实现。它确保了IDataSource具备向多个消费者广播数据变更的能力,同时支持监听器的安全动态管理,这是构建响应式、松耦合UI系统的基石。在您的开发中,如果一个数据源确实只需要通知一个监听器,那么数组中通常也只包含一个元素,但框架设计必须为更普遍的复杂场景提供支持。

