HarmonyOS 鸿蒙Next LazyForEach没有刷新index

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next LazyForEach没有刷新index

深色代码主题
复制
@ComponentV2
export struct ConditionMoreInputComp {
@Param placeholderText: string = ‘’
@Param label: string = ‘’
@Local showTxt: string = ‘’
@Param keywordsList: KeywordModel[] = []
@Event addData: (data: KeywordModel) => void
@Event removeData: (index: number) => void
dataSource: MutableArrayDataSource<KeywordModel> = new MutableArrayDataSource(this.keywordsList)

aboutToAppear(): void { this.dataSource.pushData(new KeywordModel()) }

add() { if (this.dataSource.totalCount() >= 5) { toast(‘最多添加 5 组关键词’) return } const empty = new KeywordModel() this.addData(empty) this.dataSource.pushData(empty) }

build() { Row() { if (this.label) { Text(this.label) .fontSize(15) .margin({ right: 5 }) .padding({ top: 12, bottom: 12, }) .fontColor(Colors.Color66) } List({ space: 10 }) { LazyForEach(this.dataSource, (item: KeywordModel, index: number) => { ListItem() { ItemKeyWordComp({ isFirst: index === 0, item: item, add: () => { this.add() }, remove: () => { LogUtil.error(‘删除的Index’ + index) this.dataSource.removeData(index) this.removeData(index) } }) } .backgroundColor(Color.White) }, (item: KeywordModel, index) => JSONUtil.beanToJsonStr(item) + ‘-’ + index) } .layoutWeight(1) } .alignItems(VerticalAlign.Center) } }

@ComponentV2 struct ItemKeyWordComp { @Param @Once isFirst: boolean = true @Param @Once item: KeywordModel = new KeywordModel() @Event add: () => void @Event remove: () => void

build() { Row() { Row() { if (!this.isFirst) { Row() { Text(this.item.IsContains ? ‘且包含’ : ‘且不包含’,) .fontSize(15) .fontColor(Colors.ColorAB) Image($r(‘app.media.ic_arrow_down’)) .fitOriginalSize(true) .fillColor(Colors.ColorAB) } .borderWidth({ right: 0.2 }) .alignItems(VerticalAlign.Center) .padding({ left: 5, right: 5, }) .bindMenu([ { value: ‘且包含’, action: () => { this.item.IsContains } }, { value: ‘且不包含’, action: () => { !this.item.IsContains } }, ]) .height(‘100%’) } TextInput({ text: this.item.Keyword, placeholder: ‘请输入关键词’ }) .placeholderColor(Colors.ColorAB) .placeholderFont({ size: 15 }) .maxLines(1) .caretColor(Colors.ThemeColor) .copyOption(CopyOptions.InApp) .type(InputType.Normal) .padding({ left: 5, right: 5 }) .fontSize(15) .fontColor(Colors.Color33) .maxLength(50) .enterKeyType(EnterKeyType.Next) .showPasswordIcon(false) .backgroundColor(Color.Transparent) .enableKeyboardOnFocus(false) .cancelButton({ style: CancelButtonStyle.INPUT, icon: { src: $r(‘app.media.ic_fork’), color: Colors.ColorCC, size: 14, } }) .layoutWeight(1) .onChange((value) => { this.item.Keyword = value }) .height(‘100%’) } .alignItems(VerticalAlign.Center) .height(‘100%’) .layoutWeight(1) .borderColor(Colors.ColorAB) .borderRadius(3) .borderWidth(0.2)

  <span class="hljs-title class_">Text</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">isFirst</span> ? <span class="hljs-string">' + '</span> : <span class="hljs-string">' - '</span>)
    .<span class="hljs-title function_">width</span>(<span class="hljs-number">30</span>)
    .<span class="hljs-title function_">fontSize</span>(<span class="hljs-number">15</span>)
    .<span class="hljs-title function_">textAlign</span>(<span class="hljs-title class_">TextAlign</span>.<span class="hljs-property">Center</span>)
    .<span class="hljs-title function_">fontColor</span>(<span class="hljs-title class_">Colors</span>.<span class="hljs-property">Color33</span>)
    .<span class="hljs-title function_">onClick</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-variable language_">this</span>.<span class="hljs-property">isFirst</span> ? <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">add</span>() : <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">remove</span>()
    })
    .<span class="hljs-title function_">height</span>(<span class="hljs-string">'100%'</span>)
    .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">left</span>: <span class="hljs-number">3</span> })
    .<span class="hljs-title function_">padding</span>({ <span class="hljs-attr">top</span>: <span class="hljs-number">12</span>, <span class="hljs-attr">bottom</span>: <span class="hljs-number">12</span> })
    .<span class="hljs-title function_">borderColor</span>(<span class="hljs-title class_">Colors</span>.<span class="hljs-property">ColorAB</span>)
    .<span class="hljs-title function_">borderRadius</span>(<span class="hljs-number">3</span>)
    .<span class="hljs-title function_">borderWidth</span>(<span class="hljs-number">0.2</span>)
}
.<span class="hljs-title function_">height</span>(<span class="hljs-number">40</span>)
.<span class="hljs-title function_">padding</span>({ <span class="hljs-attr">right</span>: <span class="hljs-number">1</span> })
.<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>)
.<span class="hljs-title function_">justifyContent</span>(<span class="hljs-title class_">FlexAlign</span>.<span class="hljs-property">Start</span>)

} }

从中间开始删除的话,那个Index没有变

深色代码主题
复制

export default class BasicDataSource<T> implements IDataSource {
private listeners: DataChangeListener[] = []
private mutable: T[]

constructor(list: T[]) { this.mutable = list }

hasMore(totalCount?: number): boolean { return this.totalCount() < (totalCount ?? 0) }

getDataList(): T[] { return this.mutable }

totalCount(): number { return this.mutable.length }

getData(index: number): T { return this.mutable[index] }

notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded() }) }

notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index) }) }

notifyDataChange(index: number): void { this.listeners.forEach(listener => { listener.onDataChange(index) }) }

notifyDataDelete(index: number): void { this.listeners.forEach(listener => { listener.onDataDelete(index) }) }

notifyDataMove(from: number, to: number): void { this.listeners.forEach(listener => { listener.onDataMove(from, to) }) }

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) } } }

import BasicDataSource from ‘./base/BasicDataSource’

export default class MutableArrayDataSource<T> extends BasicDataSource<T> { private dataList: T[]

constructor(list: T[] = []) { super(list) this.dataList = list }

public getDataList(): T[] { return this.dataList }

public totalCount(): number { return this.dataList.length }

public getData(index: number): T { return this.dataList[index] }

public addData(index: number, data: T) { this.dataList.splice(index, 0, data) this.notifyDataAdd(index) }

public pushDataList(dataList: T[]) { dataList.forEach((item) => { this.dataList.push(item) this.notifyDataAdd(this.dataList.length - 1) }) }

public pushData(data: T) { this.dataList.push(data) this.notifyDataAdd(this.dataList.length - 1) }

public removeData(index: number) { this.dataList.splice(index, 1) this.notifyDataDelete(index) }

public clear() { this.dataList = [] this.notifyDataReload() } }


更多关于HarmonyOS 鸿蒙Next LazyForEach没有刷新index的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

在删除一个数据项后调用reloadData方法,重建后面的数据项,以达到更新index索引的目的

深色代码主题
复制
class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: string[] = [];

public totalCount(): number { return 0; }

public getData(index: number): string { return this.originDataArray[index]; }

registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { console.info(‘add listener’); this.listeners.push(listener); } }

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

notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded(); }) }

notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index); }) }

notifyDataChange(index: number): void { this.listeners.forEach(listener => { listener.onDataChange(index); }) }

notifyDataDelete(index: number): void { this.listeners.forEach(listener => { listener.onDataDelete(index); }) }

notifyDataMove(from: number, to: number): void { this.listeners.forEach(listener => { listener.onDataMove(from, to); }) } }

class MyDataSource extends BasicDataSource { private dataArray: string[] = [];

public totalCount(): number { return this.dataArray.length; }

public getData(index: number): string { return this.dataArray[index]; }

public addData(index: number, data: string): void { this.dataArray.splice(index, 0, data); this.notifyDataAdd(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(); } }

@Entry @Component struct MyComponent { private data: MyDataSource = new MyDataSource();

aboutToAppear() { for (let i = 0; i <= 20; i++) { this.data.pushData(Hello <span class="hljs-subst">${i}</span>) } }

build() { List({ space: 3 }) { LazyForEach(this.data, (item: string, index: number) => { ListItem() { Row() { Text(item).fontSize(50) .onAppear(() => { console.info(“appear:” + item,index) }) }.margin({ left: 10, right: 10 }) } .onClick(() => { // 点击删除子组件 this.data.deleteData(index); // 重置所有子组件的index索引 this.data.reloadData(); }) }, (item: string, index: number) => item + index.toString()) }.cachedCount(5) } }

更多关于HarmonyOS 鸿蒙Next LazyForEach没有刷新index的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


JSONUtil.beanToJsonStr(item) ,我看了一下,KeywordModel在代码里只两个值,并且,添加的时候直接new,没有做数据处理,那么,jsonStr都是一样的吧?这样LazyForEach的add时候因为index 所以,是唯一的。但是remove的时候。key值没变化(只是总数少了一个)。应该渲染异常了

在HarmonyOS(鸿蒙)中,LazyForEach 组件的 index 未刷新的问题通常与数据绑定或组件内部状态管理有关。LazyForEach 用于高效地渲染列表项,但如果数据源或组件状态未正确更新,index 可能不会按预期刷新。

要解决这个问题,请检查以下几点:

  1. 数据源更新:确保在修改列表数据后,触发数据源的更新。如果数据源是一个可变集合,确保使用适当的方法来修改集合,例如使用 addremove 等方法,并通知UI层更新。

  2. 组件状态管理:检查 LazyForEach 组件及其子组件的状态管理。如果子组件依赖于外部状态(如全局状态或父组件的状态),确保这些状态在数据变化时得到正确更新。

  3. 重新渲染:在数据变化后,确保 LazyForEach 能够感知到数据变化并重新渲染。这通常依赖于数据绑定框架的自动更新机制。

  4. 组件内部逻辑:检查 LazyForEach 组件及其子组件的内部逻辑,确保没有逻辑错误导致 index 更新失败。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部