HarmonyOS鸿蒙Next中使用LazyForEach做分页查询刷新列表,把数据pushData后,出现页面跳到第一条数据的bug,如何解决
HarmonyOS鸿蒙Next中使用LazyForEach做分页查询刷新列表,把数据pushData后,出现页面跳到第一条数据的bug,如何解决

关键代码如下
Refresh({refreshing: $$this.isRefreshing, builder: this.customRefreshComponent()}){
List(){
LazyForEach(this.orderListData,(item: ShopDeviceOrderListContent)=>{
OrderListItem({orderInfo: item, copy: (id: string)=> { this.onCopy(id) }})
.width('93%').margin({top: 10}).borderRadius(16).shadow(ShadowStyle.OUTER_DEFAULT_SM)
}, (item: ShopDeviceOrderListContent) => item.id)
ListItem(){
Text("没有更多数据")
.fontSize(16)
.fontColor($r('app.color.colorText3'))
.width('100%')
.height(40)
.textAlign(TextAlign.Center)
.visibility(this.noMoreShow && this.orderListData.totalCount() > 0 ? Visibility.Visible : Visibility.None)
}
}
.width('100%')
.height('100%')
.alignListItem(ListItemAlign.Center)
.onReachEnd(()=>{
if (!this.noMoreShow){
this.initData()
}
})
}
.onRefreshing(()=>{
this.query.page = 0
this.initData()
})
initData(){
if (this.loading){
return
}
this.loading = true
efRcpClientApi.get<ShopDeviceOrderListData>({
url: deviceOrder,
query: this.query,
isParams: true
}).then((data)=>{
if (this.query.page == 0){
this.orderListData = new MyOrderDataSource()
}
if (data.data?.content != undefined){
let list : ShopDeviceOrderListContent[] = data.data.content
for (let index = 0; index < list.length; index++) {
let data : ShopDeviceOrderListContent = list[index] as ShopDeviceOrderListContent
for(let dict of this.paymentMethodDictList){
if (data.payType == dict.value){
data.payMethodName = dict.label
}
}
this.orderListData.pushData(data)
}
if (list.length < this.query.size){
//没有更多数据
this.noMoreShow = true
} else {
this.query.nextPage()
}
} else {
let bean : ErrorBean = JSON.parse(JSON.stringify(data.data)) as ErrorBean
showToast(bean.message!)
}
this.loading = false
this.isRefreshing = false
})
}
export class MyOrderDataSource extends OrderBasicDataSource {
private dataArray: ShopDeviceOrderListContent[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): ShopDeviceOrderListContent {
return this.dataArray[index];
}
public addData(index: number, data: ShopDeviceOrderListContent): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: ShopDeviceOrderListContent): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}
public changeData(index: number): void {
this.notifyDataChange(index);
}
}
export class OrderBasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: ShopDeviceOrderListContent[] = [];
/*constructor(list: CustomBeanType[]) {
this.originDataArray = list
}*/
public totalCount(): number {
return 0;
}
public getData(index: number): ShopDeviceOrderListContent {
return this.originDataArray[index];
}
public registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
//console.info('add listener');
this.listeners.push(listener);
}
}
public unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
//console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
public notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
public notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
public notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
public notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
public notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
public notifyDatasetChange(operations: DataOperation[]): void {
this.listeners.forEach(listener => {
listener.onDatasetChange(operations);
})
}
}
更多关于HarmonyOS鸿蒙Next中使用LazyForEach做分页查询刷新列表,把数据pushData后,出现页面跳到第一条数据的bug,如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html
如果你是想要在到onReachEnd的时候就跳回到第一条listitem的话,使用scrollEdge就能做到,使用下面的方法:
private scroller: ListScroller = new ListScroller()
.onReachEnd(() =>{
if (!this.noMoreShow){
this.initData()
this.scroller.scrollEdge(Edge.Top)
}
})
如果理解的意思有偏差,麻烦提供下ShopDeviceOrderListContent、efRcpClientApi、OrderListItem自定义组件、this.query的定义也要麻烦发下,还有视频现象是不是忘记了上传。
或者提供个更加简单的场景复现demo一起看下呢
更多关于HarmonyOS鸿蒙Next中使用LazyForEach做分页查询刷新列表,把数据pushData后,出现页面跳到第一条数据的bug,如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中使用LazyForEach进行分页查询时,如果遇到数据pushData后页面跳到第一条数据的bug,可能是因为LazyForEach的状态管理问题。LazyForEach在数据源发生变化时会重新渲染列表,导致页面跳回第一条数据。
解决方法可以通过以下步骤实现:
-
保持数据源稳定性:确保数据源在
pushData时不会触发LazyForEach的重新渲染。可以通过在数据源中添加唯一标识符(如ID)来避免重复渲染。 -
使用
@State或@Link管理数据:通过@State或@Link修饰的数据源可以更好地控制列表的渲染行为,避免不必要的刷新。 -
手动控制滚动位置:在
pushData后,手动设置列表的滚动位置,避免跳回第一条数据。可以通过Scroll组件的scrollTo方法实现。 -
优化数据更新逻辑:在
pushData时,尽量避免直接修改数据源,而是通过setState或update方法来更新数据,从而减少不必要的渲染。
通过这些方法,可以有效解决LazyForEach在分页查询时页面跳回第一条数据的问题。
在HarmonyOS鸿蒙Next中使用LazyForEach进行分页查询刷新列表时,如果出现页面跳到第一条数据的问题,通常是由于数据源更新后,LazyForEach重新渲染导致的。解决方法如下:
- 保持数据源不变:在分页查询时,确保新数据是追加到现有数据源中,而不是替换整个数据源。
- 使用Key机制:为LazyForEach中的每一项设置唯一Key,确保在数据更新时只重新渲染新增的项,而不是整个列表。
- 控制滚动位置:在数据更新后,手动控制列表的滚动位置,避免跳转到第一条数据。
示例代码:
// 假设dataSource是当前数据源,newData是新查询的数据
dataSource.push(...newData);
// 更新列表
listController.scrollToIndex(previousScrollIndex);
通过以上方法,可以有效避免页面跳到第一条数据的问题。

