MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

鸿蒙开发(九十二):LazyForEach 修改数据

2025-01-23 17:27 huorong 精选文章 4 ℃ 0 评论

本节内容基于鸿蒙开发(八十九):LazyForEach 数据懒加载

修改指定位置数据

第一步,在数据源中添加一个修改指定位置数据的功能 changeData(index: number, data: Article)。

修改数据一定要调用 notifyDataChange 去通知 LazyForEach 数据已更改,请刷新 UI。

/**
 * 文章数据源
 */
class ArticleDataSource extends BaseDataSource<Article> {
  /**
   * 改变指定位置的数据
   *
   * @param index 位置
   * @param data 数据
   */
  changeData(index: number, data: Article) {
    // 修改指定位置的数据
    this.datas.splice(index, 1, data)
    // 通知 LazyForEach 刷新 UI
    this.notifyDataChange(index)
  }
}

第二步,给 ListItem 添加一个点击事件。

LazyForEach(this.articleDataSource, (item: Article, index: number) => {
  ListItem() {
    Item({ article: item })
  }
  .onClick(() => {
    // 待修改的数据的位置
    const position = this.articleDataSource.datas.indexOf(item)
    // 修改后的数据
    const article = new Article(`${this.articleDataSource.datas.length + index}`, "修改后的数据")
    // 修改数据
    this.articleDataSource.changeData(position, article)
  })
}, (item: Article) => item.id)

运行结果:

从运行结果来看,没有任何问题。

修改属性

上面是直接使用新数据去替换原数据。

如果在原数据基础上直接修改会怎样呢?

改写点击事件里面的代码:

LazyForEach(this.articleDataSource, (item: Article, index: number) => {
  ListItem() {
    Item({ article: item })
  }
  .onClick(() => {
    // 待修改的数据的位置
    const position = this.articleDataSource.datas.indexOf(item)
    // 修改后的数据
    item.title = "修改后的数据"
    // 修改数据
    this.articleDataSource.changeData(position, title)
  })
}, (item: Article) => item.id)

运行结果:

从运行结果来看,没有任何效果。

这是怎么回事呢?

LazyForEach 只有在元素的 key 发生改变时才会去刷新 UI。如果我们只是修改了某个元素里的属性,LazyForEach 是感知不到数据发生更改的。

怎么解决呢?

既然 LazyForEach 感知不到属性的变化,那么我们就可以对症下药。使用 @Observed/@ObjectLink 装饰器,让 LazyForEach 能够感知到属性的更改,从而刷新 UI。

第一步,给 Article 类上加上 @Observed 装饰器:

/**
 * 文章
 */
@Observed
class Article {
  /**
   * ID
   */
  id: string
  /**
   * 标题
   */
  title: string

  constructor(id: string, title: string) {
    this.id = id
    this.title = title
  }
}

第二步,在 Item 组件里,给 article 属性添加 @ObjectLink 装饰器:

@Component
struct Item {
  @ObjectLink article: Article

  aboutToAppear() {
    console.log(`组件已创建:${this.article.title}`)
  }

  build() {
    Text(this.article.title)
      .fontSize(30)
  }
}

运行结果:

从运行结果来看,成功修改元素的属性。

总结:

  • 修改数据一定要调用 notifyDataChange 去通知 LazyForEach 数据已更改,请刷新 UI。
  • 每次修改数据时查询数据项在数组中的位置。
  • 修改元素的属性时需搭配 @Observed/@ObjectLink 使用。


Tags:@lazy

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言