HarmonyOS 解析Json数据添加到数据源不刷新UI

@Entry  
@Component  
struct DishSearchPage {  
  @State articleList: Array<Article> = []  
  res = `{"code":0,"data":[{"id":"001","title":"第0篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"002","title":"第1篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"003","title":"第2篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"004","title":"第4篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"005","title":"第5篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"006","title":"第6篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100}]}`;  
  aboutToAppear(): void {  
    let articleRes: ArticleRes = JSON.parse(this.res)  
    articleRes?.data?.forEach((v) => {  
  
      // this.articleList.push(JSON.parse(JSON.stringify(v)))  
  
      this.articleList.push(JSON.parse(JSON.stringify(v)))  
    })  
  }  
  
  build() {  
    List() {  
      ForEach(this.articleList, (item: Article) => {  
        ListItem() {  
          ArticleCard({  
            article: item  
          })  
            .margin({ top: 20 })  
        }  
      }, (item: Article) => item.id)  
    }  
    .padding(20)  
    .scrollBar(BarState.Off)  
    .backgroundColor(0xF1F3F5)  
  }  
}  
  
@Component  
struct ArticleCard {  
  @ObjectLink article: Article;  
  
  handleLiked() {  
    this.article.isLiked = !this.article.isLiked;  
    this.article.likesCount = this.article.isLiked ? this.article.likesCount + 1 : this.article.likesCount - 1;  
  }  
  
  build() {  
    Row() {  
      Image($r('app.media.icon'))  
        .width(80)  
        .height(80)  
        .margin({ right: 20 })  
  
      Column() {  
        Text(this.article.title)  
          .fontSize(20)  
          .margin({ bottom: 8 })  
        Text(this.article.brief)  
          .fontSize(16)  
          .fontColor(Color.Gray)  
          .margin({ bottom: 8 })  
  
        Row() {  
          Text(this.article.likesCount.toString())  
            .fontSize(16)  
        }  
        .justifyContent(FlexAlign.Center)  
      }  
      .alignItems(HorizontalAlign.Start)  
      .width('80%')  
      .height('100%')  
    }  
    .padding(20)  
    .borderRadius(12)  
    .height(120)  
    .width('100%')  
    .justifyContent(FlexAlign.SpaceBetween)  
    .backgroundColor(this.article.isLiked ? Color.Blue : '#FFECECEC')  
    .onClick(() => this.handleLiked())  
  }  
}  
  
@Observed  
class ArticleRes {  
  code: number = -1  
  data: Array<Article> = []  
}  
  
@Observed  
class Article {  
  id: string;  
  title: string;  
  brief: string;  
  isLiked: boolean;  
  likesCount: number;  
  
  constructor(id: string, title: string, brief: string, isLiked: boolean, likesCount: number) {  
    this.id = id;  
    this.title = title;  
    this.brief = brief;  
    this.isLiked = isLiked;  
    this.likesCount = likesCount;  
  }  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.

let articleRes: ArticleRes = JSON.parse(this.res)

articleRes?.data?.forEach((v) => this.articleList.push(v))

解析Json数据 然后添加到列表的List就不行。

[  
  new Article('001', '第0篇文章', '文章简介内容', false, 100),  
  new Article('002', '第1篇文章', '文章简介内容', false, 100)  
].forEach((v) => {  
  this.articleList.push(v)  
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

new的就可以 为什么呢?

场景就是这样的 接口返了一个类似ArticleRes的json数据 想问下要怎么操作才能让数据源数组项子属性变化 ui跟着变化呢?

这种要怎么刷新呢?

HarmonyOS
2024-09-26 10:55:44
1494浏览
收藏 0
回答 2
回答 2
按赞同
/
按时间
鱼弦CTO
1

在HarmonyOS的ArkUI中,​​@State​​​ 和 ​​@Observed​​ 数据的变化会自动触发UI更新。但是你遇到的问题是,当从JSON解析并添加到数组后,UI没有及时刷新。这通常与对象的引用和响应式系统有关。

### 原因分析

当你直接从JSON解析数据并添加到 ​​@State​​ 的数组中时,这些新对象可能没有被正确地观察到,因此无法触发UI更新。相比之下,通过 ​​new​​ 关键字创建的对象因为是在受控环境下生成的,所以能够被正确地观察到。

## 解决方案

可以通过显式构造新的 ​​Article​​ 对象来确保这些对象被正确观察到。以下是优化后的代码示例:

### 父组件代码

// MainPage.ets
import { CommonDataSource } from './CommonDataSource';
import { ArticleCard } from './ArticleCard';

@Entry
@Component
struct DishSearchPage {
    @State articleList: Array<Article> = [];
    private res: string = `{"code":0,"data":[{"id":"001","title":"第0篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"002","title":"第1篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"003","title":"第2篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"004","title":"第4篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"005","title":"第5篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100},{"id":"006","title":"第6篇文章","brief":"文章简介内容","isLiked":false,"likesCount":100}]}`;

    aboutToAppear(): void {
        let articleRes: ArticleRes = JSON.parse(this.res);
        articleRes?.data?.forEach((v) => {
            // 使用构造函数创建新的 Article 实例
            let newArticle = new Article(v.id, v.title, v.brief, v.isLiked, v.likesCount);
            this.articleList.push(newArticle);
        });
    }

    build() {
        List() {
            ForEach(this.articleList, (item: Article) => {
                ListItem() {
                    ArticleCard({
                        article: item
                    }).margin({ top: 20 });
                }
            }, (item: Article) => item.id)
        }
        .padding(20)
        .scrollBar(BarState.Off)
        .backgroundColor(0xF1F3F5);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

### 子组件代码

// ArticleCard.ets
@Component
struct ArticleCard {
    @ObjectLink article: Article;

    handleLiked() {
        this.article.isLiked = !this.article.isLiked;
        this.article.likesCount = this.article.isLiked ? this.article.likesCount + 1 : this.article.likesCount - 1;
    }

    build() {
        Row() {
            Image($r('app.media.icon'))
                .width(80)
                .height(80)
                .margin({ right: 20 });

            Column() {
                Text(this.article.title)
                    .fontSize(20)
                    .margin({ bottom: 8 });

                Text(this.article.brief)
                    .fontSize(16)
                    .fontColor(Color.Gray)
                    .margin({ bottom: 8 });

                Row() {
                    Text(this.article.likesCount.toString())
                        .fontSize(16);
                }
                .justifyContent(FlexAlign.Center);
            }
            .alignItems(HorizontalAlign.Start)
            .width('80%')
            .height('100%');
        }
        .padding(20)
        .borderRadius(12)
        .height(120)
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        .backgroundColor(this.article.isLiked ? Color.Blue : '#FFECECEC')
        .onClick(() => this.handleLiked());
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

### 数据模型

@Observed
class ArticleRes {
    code: number = -1;
    data: Array<Article> = [];
}

@Observed
class Article {
    id: string;
    title: string;
    brief: string;
    isLiked: boolean;
    likesCount: number;

    constructor(id: string, title: string, brief: string, isLiked: boolean, likesCount: number) {
        this.id = id;
        this.title = title;
        this.brief = brief;
        this.isLiked = isLiked;
        this.likesCount = likesCount;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

### 总结

通过调用 ​​Article​​ 构造函数创建新的 ​​Article​​ 实例,可以确保这些实例被正确观察到,从而触发UI更新。当你直接从JSON解析并赋值时,由于这些对象没有通过 ​​Observed​​ 相关机制生成,可能不会触发UI更新。因此,使用显式构造的新对象可以解决这个问题。

分享
微博
QQ
微信
回复
2024-09-26 18:59:11
zbw_apple

使用三方库 class-transformer:https://ohpm.openharmony.cn/#/cn/detail/class-transformer

Json转Class 就行了。

分享
微博
QQ
微信
回复
2024-09-26 17:48:10


相关问题
HarmonyOS 更新数据UI刷新
995浏览 • 1回复 待解决
lazyforeach替换数据源解决方案
1693浏览 • 1回复 待解决
HarmonyOS 卡片添加到负一屏
1337浏览 • 1回复 待解决
HarmonyOS picker选择器的数据源问题
814浏览 • 1回复 待解决
HarmonyOS JSON数据解析问题
773浏览 • 1回复 待解决
修改ForEach使用的数据对象,UI刷新
2930浏览 • 1回复 待解决
恭喜您,今日已阅读两篇内容,特奖励+2声望, 快来领取吧。