HarmonyOS +LazyForEach懒加载在删除界面元素时,被删除的元素与当前被选中的不一致
【摘要】 1.问题说明:使用LazyForEach进行遍历数据,例如:当首次进入,选中列表中第2条数据,点击删除,第二条数据被正常删除;这个时候再次点击当前被刷新之后的列表中的第二条数据,点击删除列表,会出现第二条数据没有被删掉成功。而当前列表中的第三条数据却被删除;2.原因分析:当出现问题时,发现,第一次点击删除正常的前提下,索引传入的值为1,待列表被刷新之后,依然选择第二条数据时,传入的索引变成了...
1.问题说明:
使用LazyForEach进行遍历数据,例如:当首次进入,选中列表中第2条数据,点击删除,第二条数据被正常删除;这个时候再次点击当前被刷新之后的列表中的第二条数据,点击删除列表,会出现第二条数据没有被删掉成功。而当前列表中的第三条数据却被删除;
2.原因分析:
当出现问题时,发现,第一次点击删除正常的前提下,索引传入的值为1,待列表被刷新之后,依然选择第二条数据时,传入的索引变成了2
List(){
LazyForEach(this.data,(item:string,index:number)=>{
ListItem(){
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info("Kingson appear:" + item)
})
}.margin({ left: 10, right: 10 })
}.onClick(() => {
// 点击追加子组件
this.data.pushData(`Hello ${this.data.totalCount()}`);
})
.swipeAction({
end:{
builder:()=>{
this.itemEnd(index);
},
}
})
},(item: string, index: number)=>item)
}.cachedCount(5)
3.解决思路:
找出如上index索引传入的值错误的原因;从传入的值来看,无论是第二次、第三次进行点击,获取的index值依然是首次删除前的索引,而非基于当前列表下的最新索引值;虽然数组刷新了,但list中的索引没有变。这个时候就要寻找LazyForEach 混乱的原因
4.解决方案:
LazyForEach 有三个参数,第一个是要传入的集合,第二个是回调,第三个参数是可以影响是否唯一、避免混乱的;最初,第三个参数传入的是:(item: string)=>item,造成了索引混乱,接着改成(item: string, index: number)=>item+index.toString()之后索引的值可以正常改变
具体代码:
BasicDataSource.etc
export class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): string {
return this.originDataArray[index];
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.ADD, index: index}]);
})
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.CHANGE, index: index}]);
})
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.DELETE, index: index}]);
})
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
// 写法2:listener.onDatasetChange(
// [{type: DataOperationType.EXCHANGE, index: {start: from, end: to}}]);
})
}
notifyDatasetChange(operations: DataOperation[]): void {
this.listeners.forEach(listener => {
listener.onDatasetChange(operations);
})
}
}
MyDataSource.etc
@Observed
class MyDataSource extends BasicDataSource {
@Track dataArray: string[] = [];
public getDataArr(): string[] {
return this.dataArray;
}
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): string {
return this.dataArray[index];
}
public pushData(data: string): 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 reloadData(): void {
this.notifyDataReload();
}
}
viewLazyForEachTmp.etc
@Component
export struct viewLazyForEachTmp{
pathStack: NavPathStack = new NavPathStack();
private data: MyDataSource = new MyDataSource();
@State arrList:Array<string>=["1","2"]
aboutToAppear() {
for (let i = 0; i <= 10; i++) {
this.data.pushData(`Hello ${i}`)
this.arrList.push(`Hello ${i}`)
}
}
@Builder itemEnd(index: number) {
// 构建尾端滑出组件
Button({ type: ButtonType.Normal }) {
Text("删除")
.width("25%")
.height("100%")
.backgroundColor("#ff00")
.fontSize(14)
.fontColor("#ffffff")
.textAlign(TextAlign.Center)
}
.onClick(() => {
// this.messages为列表数据源,可根据实际场景构造。点击后从数据源删除指定数据项。
this.data.deleteData(index)
// 重置所有子组件的index索引
this.data.reloadData();
console.info("Kingson 删除 index->"+index)
console.info("Kingson 删除 index->"+JSON.stringify(this.data.getDataArr()))
})
}
build() {
NavDestination(){
List(){
LazyForEach(this.data,(item:string,index:number)=>{
ListItem(){
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info("Kingson appear:" + item)
})
}.margin({ left: 10, right: 10 })
}.onClick(() => {
// 点击追加子组件
this.data.pushData(`Hello ${this.data.totalCount()}`);
})
.swipeAction({
end:{
builder:()=>{
this.itemEnd(index);
},
}
})
},(item: string, index: number)=>item+index.toString())
}.cachedCount(5)
}.title("懒加载")
.onBackPressed(() => {
const popDestinationInfo = this.pathStack.pop(); // 弹出路由栈栈顶元素
console.info('pop' + '返回值' + JSON.stringify(popDestinationInfo));
return true
})
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
})
}
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)