#HarmonyOS NEXT体验官# 基于HTTP的列表数据加载(二)

Oxide_xyn
发布于 2024-8-9 17:12
浏览
1收藏

基于HTTP的列表数据加载(二)

#HarmonyOS NEXT体验官# 基于HTTP的列表数据加载(二)-鸿蒙开发者社区

书接上文,在上一篇文章中我们开启了模块的网络访问权限,并分析了公共组件的工作逻辑。下面在本篇中我们来看看核心业务逻辑Index.ets和Detail.ets的内容。

代码实现

Index.ets代码

下面是商品列表页面Index.ets的代码。当我们的应用启动时,首先打开的就是商品列表页面:

import GoodsItem from '../components/GoodItem'
import { GoodInfo } from '../Types/GoodsTypes';
import { http } from '@kit.NetworkKit';

@Entry
@Component
struct Index {
  @State goodsList: GoodInfo[]|null = null
  @State loading: boolean = false
  
  // 2)生命周期函数,每次页面组件显示时触发
  onPageShow(): void {
    this.dataRequest()
  }
  // 1)请求函数
  dataRequest(): void {
    let httpRequest = http.createHttp()
    this.loading = true
    httpRequest.request(
      'localhost:3000/goodsList',
    ).then((res) => {
      // 更新商品列表数据,触发重新渲染
      this.goodsList = JSON.parse(res.result as string).goodsList
    }).catch((err:Error) => {
      console.error('request error: '+ JSON.stringify(err))
    }).finally(() => {
      this.loading = false
      httpRequest.destroy()
    })
  }

  build() {
    Column(){
      List(){
        // 3)循环渲染
        ForEach(this.goodsList, (item:GoodInfo) => {
          GoodsItem({goodInfo: item})
        })
      }
      .height('100%')
      .alignListItem(ListItemAlign.Center)
    }
    .height('100%')
    .width('100%')
  }
}
  • 代码1处声明了方法dataRequest,其中封装了发送HTTP请求获取列表数据的相关逻辑。本例中使用的HTTP请求使用GET方法,不用传参。通过访问后端接口hostname/goodsList即可直接获得商品数据。在本例中这个后端接口会直接以数组形式返回商品列表数据。

实际开发中可能会携带一些用户信息相关的数据给服务端,如用户id,进行类似个性化推荐类型的处理)。

  • 代码2我们使用了一个组件生命周期函数onPageShow。每当页面显示的时候都会触发该事件。即第一次进入列表页、或者从别的页面跳转都列表时,都会触发这个生命周期函数并执行逻辑重新请求商品列表数据。
  • 最后,在代码3处,通过ForEach语句对GoodsList数组进行遍历,并为每一个遍历到数据元素创建了一个对应的GoodsItem组件。并且在创建GoodsItem组件的同时,将对应的商品信息传入该组件。这样在GoodsItem中就可以通过@prop修饰的属性(本例中是goodInfo)接收到商品信息了。

可以看出,在使用了GoodsItem组件后,商品列表页面的的布局代码变得非常简洁。

Detail.ets代码

import { router } from '@kit.ArkUI';
import { GoodInfo } from '../Types/GoodsTypes';
import { http } from '@kit.NetworkKit';

interface DetailRouterParams {
  id: string
}

@Entry
@Component
struct Detail {
  @State goodId: string = '';
  @State goodInfo: GoodInfo|null = null;
  @State loading: boolean = false

  // 1)
  onPageShow(): void {
    // 获取商品id
   this.goodId = (router.getParams() as DetailRouterParams).id
    // 请求商品数据
    this.getDetail(this.goodId)
  }

  // 2)
  getDetail(id:string): void {
    let httpRequest = http.createHttp()
    this.loading = true
    httpRequest.request(
      // get请求拼接查询串
      `localhost:3000/goodDetail?id=${id}`,
    ).then((res) => {
      // 更新商品详情数据,触发重新渲染
      this.goodInfo = JSON.parse(res.result as string).detail
    }).catch((err:Error) => {
      console.error('request error: '+ JSON.stringify(err))
    }).finally(() => {
      this.loading = false
      httpRequest.destroy()
    })
  }

  build() {
    Column() {
      Image(this.goodInfo?.imgUrl)
        .height(300)
      Text(this.goodInfo?.goodName)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .margin({bottom:5})
      Row(){
        Text('价格:')
          .fontSize(22)
        Text(this.goodInfo?.goodPrice)
          .fontSize(22)
      }
      .margin({bottom:20})
      Text(this.goodInfo?.description)
        .fontSize(16)
        .textIndent(32)
        .textAlign(TextAlign.JUSTIFY)
    }
    .height('100%')
    .width('100%')
    .alignItems(HorizontalAlign.Center)
    .padding(20)
  }
}

在Detail页面中,代码1处同样使用了onPageShow生命周期函数。并编写了如下逻辑:

  • 首先,每当进入Detail页面时,通过router.getParams()方法获取路由中的当前商品id。

还记得这个路由参数是哪里传过来的么?不记得的话可以网上看一下GoodsItem组件的点击事件。

在该事件中进行页面跳转的同时,还向router传入了组件当前商品数据的id。然后,调用getDetail方法并将获取到的商品id传入;

  • 下一步,在代码2getDetail方法中,封装了请求商品详情数据的HTTP请求逻辑。这里请求同样使用GET方法。并将商品id作为查询参数拼接到了URL中。这样就可以通过id告诉服务器是要获取哪一个商品的的信息了;最后,在promise处理函数中用服务接口返回的数据去更新详情数据this.goodInfo,从而触发页面更新渲染,实现了详情页面的刷新。

结语

以上就是一个基于HTTP请求的商品列表页面的完整例子。希望可以给各位提供一个参考思路,欢迎大家交流。

标签
已于2024-8-9 17:12:26修改
收藏 1
回复
举报
回复
    相关推荐