【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十八)

news2024/11/18 1:54:09

课程地址: 黑马程序员HarmonyOS4+NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发

(本篇笔记对应课程第 28 节)

P28《27.网络连接-Http请求数据》

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

案例:

在这里插入图片描述

这里不懂后端假设服务器的前端小伙伴就需要课程源码资料了,在课程说明里有获取课程资料的方法,我按照说明获取了如下链接:

黑马《HarmonyOS4.0开发应用从入门到实战》
在线学习:
https://www.bilibili.com/video/BV1Sa4y1Z7B1/
网盘链接:
https://pan.baidu.com/s/1EKJct0IoPRHQXboKrG4TCw?pwd=9988
提取码:9988

成功提取了课程相关资料~

新建一个页面路由;执行相关命令启动服务器:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ShopPage.ets 文件中的代码如下:

在这里插入图片描述

在这里插入图片描述

商店列表数组的数据类型是 ShopInfo 类型,由于这是与页面视图渲染相关的数据,该类型定义在 viewmodel 目录下的一个 ts 文件中:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

页面渲染部分即build函数中的代码如下:

在这里插入图片描述

在这里插入图片描述

子组件 ShopItem.ets 中的代码如下:

在这里插入图片描述

其中,Text 的 ellipsisTextOverFlow 属性已不存在,查看文档,发现已替换为了以下属性:在这里插入图片描述

新建 model 文件夹,其中的文件用于处理数据,在其中新建 ShopModel.ts 文件,在这个文件中获取商铺列表数据:

在这里插入图片描述

在这里插入图片描述

由于 request 方法返回的是一个 Promise ,通过这个请求获取到的 ShopInfo类型的数据是异步的,所以需要将 getShopList 方法的返回值写成 Promise 类型(Line 8),同时将方法中的http请求过程封装成返回一个Promise:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

使用这个调用接口的方法:

在这里插入图片描述

下滑加载更多效果:添加 onReachEnd 函数,由于下滑触底时有回弹动画效果,会导致该触底函数被触发两次,因此增加一个 isLoading 变量来进行控制(实践中发现该问题好像不存在了):

在这里插入图片描述

在这里插入图片描述

此时再次观察上滑效果, “触底” 会触发 2 次,但加载数据只触发 1次,正是我们想要的效果。

增加翻页与查询效果:

在这里插入图片描述

此时发现问题,上滑查询下一页数据后,将之前的数据替换掉了,这是因为我们直接将新查询到的数据赋值给了 this.shops,应该改为将新查询到的数据追加到 this.shops 中;同时在查询成功后将 isLoading 的值改回false, 不然只会查询一次。

在这里插入图片描述

没有新的数据后,触底时仍然会请求数据,不合理。增加 isMore 变量控制,初始为true,没有更多数据后不再请求。

在这里插入图片描述

在这里插入图片描述

实践:

按照视频中的页面效果与代码,写好静态页面。过程中遇到如下报错:

在这里插入图片描述

猜测是图片问题,但具体什么问题,不知晓。只好问度娘咯。

在这里插入图片描述

找到解析同款报错的这篇文章:DevEco Studio 报错only contain [a-zA-z0-9_].

在这里插入图片描述

将图片名字改为 1_1 后报错消失。

鸿蒙中这个数组[ r ( ′ a p p . m e d i a . 1 1 ′ ) , r('app.media.1_1'), r(app.media.11),r(‘app.media.1_2’)]怎么定义类型?(不太懂,待解决)

在这里插入图片描述

在这里插入图片描述

暂时 ignore 了

在这里插入图片描述

// ShopPage.ets

import { Header } from '../components/CommonComponents'
import ShopInfo from '../viewmodel/ShopInfo'
import ShopItem from '../views/ShopItem'

@Entry
@Component
struct ShopPage {
  @State shops: ShopInfo[] = []

  aboutToAppear(){
    // 加载商品数据
    this.loadShopInfo()
  }

  build() {
    Column({space:10}) {
      Header({title:'商铺列表'})

      List({space:10}){
        ForEach(this.shops, shop=>{
          ListItem(){
            ShopItem({shop:shop})
          }
        })
      }
        .padding({left:14,right:14})
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#efefef')
  }

  loadShopInfo(){
    // TODO 加载数据
    let shops = [
      {
        id:1,
        name:'新白鹿餐厅(运河上街店)',
        images:[
          $r('app.media.1_1'),
          $r('app.media.1_2')
        ],
        area:'运河上街',
        address:'台州路运河上街购物中心F5',
        avgPrice:61,
        comments:8045,
        score:47,
        openHours:'10:39-21:00'
      },
      {
        id:2,
        name:'新白鹿餐厅(运河上街店)',
        images:[
          $r('app.media.1_1'),
          $r('app.media.1_2')
        ],
        area:'运河上街',
        address:'台州路运河上街购物中心F5',
        avgPrice:61,
        comments:8045,
        score:47,
        openHours:'10:39-21:00'
      }
    ]

    // 给图片加上服务器地址前缀
    /*shops.forEach(s => {
      s.images.forEach((src,i) => {
        s.images[i] = 'http://localhost:3000' + src
      })
    })*/

    this.shops = shops

  }
}
// ShopItem.ets

import ShopInfo from '../viewmodel/ShopInfo'

@Component
export default struct ShopItem {
  shop:ShopInfo

  build() {
    Column({space:5}){
      Row(){
        Text(this.shop.name)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .textOverflow({overflow: TextOverflow.Ellipsis})
      }
        .width('100%')

      Row(){
        Text(this.shop.address)
          .fontColor('a3a3a3')
          .textOverflow({overflow: TextOverflow.Ellipsis})
      }
      .width('100%')

      Row(){
        Text('★★★★★')
          .fontColor(Color.Orange)
        Text((this.shop.score/10).toString())
          .fontColor(Color.Orange)
          .margin({right:10})
        Text(`${this.shop.comments}`)
        Blank()
        Text(`¥${this.shop.avgPrice}/人`)
      }
      .width('100%')

      Row({space:10}){
        ForEach(this.shop.images,img =>{
          Image(img)
            .width('50%')
            .height(100)
        })

      }
      .width('100%')

    }
      .backgroundColor('#fff')
      .borderRadius(10)
      .padding(12)
  }
}
// ShopModel.ts

import http from '@ohos.net.http'
import ShopInfo from '../viewmodel/ShopInfo'


class ShopModel{
  baseURL:string = 'localhost:3000'
  pageNo:number = 1

  getShopList(): Promise<ShopInfo[]>{
    return new Promise((resolve,reject) => {
      // 1、创建http的请求对象
      let httpRequest = http.createHttp()
      // 2、发送请求
      httpRequest.request(
        `${this.baseURL}/shops?pageNo=${this.pageNo}&pageSize=3`,
        {
          method:http.RequestMethod.GET
        }
      )
        .then(resp => {
          if(resp.responseCode === 200){
            // 查询成功
            console.log('查询商铺成功!',resp.result)
            resolve(JSON.parse(resp.result.toString()))
          }else{
            console.log('查询商铺信息失败!error:',JSON.stringify(resp))
            reject('查询商铺失败')
          }

        })
        .catch(error => {
          console.log('查询商铺信息失败!error:',JSON.stringify(error))
        })
    })

  }
}

const shopModel = new ShopModel
export default shopModel as ShopModel
// ShopInfo.ts

export default class ShopInfo {
  id:number
  name:string
  // @ts-ignore
  images:Resource[]
  area:string
  address:string
  avgPrice:number
  comments:number
  score:number
  openHours:string
}

在这里插入图片描述

将 下载到的课程资料中相应项目中的 shopServer 文件夹整体复制到自己的项目中:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在浏览器中输入接口访问地址,测试服务器:

在这里插入图片描述

在这里插入图片描述

将获取数据的代码修改为调用接口从服务器获取:

在这里插入图片描述

// ShopPage.ets

import { Header } from '../components/CommonComponents'
import ShopInfo from '../viewmodel/ShopInfo'
import ShopItem from '../views/ShopItem'
import ShopModel from '../model/ShopModel'

@Entry
@Component
struct ShopPage {
  @State shops: ShopInfo[] = []
  isLoading:boolean = false
  isMore:boolean = true

  aboutToAppear(){
    // 加载商品数据
    ShopModel.pageNo = 1
    this.loadShopInfo()
  }

  build() {
    Column({space:10}) {
      Header({title:'商铺列表'})

      List({space:10}){
        ForEach(this.shops, shop=>{
          ListItem(){
            ShopItem({shop:shop})
          }
        })
      }
        .padding({left:14,right:14})
        .layoutWeight(1)
        .onReachEnd(()=>{
          console.log('触底了!')
          if(!this.isLoading && this.isMore){
            this.isLoading = true
            ShopModel.pageNo++
            this.loadShopInfo()
          }
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#efefef')
  }

  loadShopInfo(){
    // TODO 加载数据
    /*let shops = [
      {
        id:1,
        name:'新白鹿餐厅(运河上街店)',
        images:[
          $r('app.media.1_1'),
          $r('app.media.1_2')
        ],
        area:'运河上街',
        address:'台州路运河上街购物中心F5',
        avgPrice:61,
        comments:8045,
        score:47,
        openHours:'10:39-21:00'
      },
      {
        id:2,
        name:'新白鹿餐厅(运河上街店)',
        images:[
          $r('app.media.1_1'),
          $r('app.media.1_2')
        ],
        area:'运河上街',
        address:'台州路运河上街购物中心F5',
        avgPrice:61,
        comments:8045,
        score:47,
        openHours:'10:39-21:00'
      }
    ]*/

    // 加载数据
    ShopModel.getShopList()
      .then(shops => {
        // 给图片加上服务器地址前缀
        shops.forEach(s => {
          s.images.forEach((src,i) => {
            s.images[i] = 'http://localhost:3000' + src
          })
        })

        this.shops = this.shops.concat(shops)

        this.isLoading = false
        if(!shops || shops.length === 0){
          this.isMore = false
        }
      })

    // 给图片加上服务器地址前缀
    /*shops.forEach(s => {
      s.images.forEach((src,i) => {
        s.images[i] = 'http://localhost:3000' + src
      })
    })*/

    // this.shops = shops

  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1867583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网易严选礼品卡有什么用?

网易严选的礼品卡可以在网易商城里买东西 但是现在好多人买东西基本上都用的是淘宝京东之类的 很少会有人用网易吧 但是最近我朋友送了我几张网易的卡&#xff0c;我自己也用积分兑换一张&#xff0c;一直不知道怎么用 最后还是在收卡云上转让出去了&#xff0c;价格高不说…

引用别的组件

在脚本中&#xff0c;也可以引用别的物体下的组件。 第一种办法&#xff0c; &#xff08;1&#xff09;添加一个变量&#xff0c; public GameObject bgmNode ; 然后在检查器里指定这个引用。 例如&#xff1a;在背景音乐空物体下面有个Audio Source组件 游戏主控脚本代码…

简单的springboot整合activiti5.22.0

简单的springboot整合activiti5.22.0 1. 需求 我们公司原本的流程服务是本地workflow模块以及一个远程的webService对应的activiti服务&#xff0c;其中activiti版本为5.22.0&#xff0c;之前想将activiiti5.22.0进行升级&#xff0c;选择了camunda&#xff0c;也对项目进行了…

Houdini 通过wedge来做模拟参数对比 (PDG TOP)

我们的设定如下例子 这是个简单的布料悬挂的例子。上方两个角分别被固定住了&#xff0c;然后在distance约束下布料下垂。 我们现在的目的是想要对比不同的streach stiffness对模拟的影响。 第一步&#xff1a;找到stiffness参数&#xff0c;右键expression->edit expre…

centos7迁移部分成功

早闻CentOS不再维护的消息&#xff0c;确实有些遗憾&#xff0c;毕竟这个系统好用又简单&#xff0c;已经成为了我们工作中的一种习惯。然而&#xff0c;2024年6月30日这一天如约而至&#xff0c;CentOS 7停止维护后&#xff0c;随之而来的安全漏洞又该如何防范&#xff1f;系统…

华为云x86架构下部署mysql

华为云x86架构下部署mysql 1. 配置X86架构ESC2. 查看本系统中有没有安装mariadb相关的组件&#xff0c;有则卸载3. 安装mysql4. 启动mysql5. 登录MySQL&#xff0c;修改密码&#xff0c;开放访问权限 1. 配置X86架构ESC 2. 查看本系统中有没有安装mariadb相关的组件&#xff0c…

餐饮行业气体泄露风险预警:可燃气体报警器的校准检测策略

在餐饮行业中&#xff0c;使用天然气、液化石油气等可燃气体作为烹饪能源是普遍现象。 然而&#xff0c;气体泄露问题时常威胁着餐饮场所的安全&#xff0c;一旦发生泄露&#xff0c;可能导致火灾、爆炸等严重事故。 因此&#xff0c;为了确保餐饮场所的安全&#xff0c;安装…

十年,亚马逊云科技合作伙伴网络开启AI新征程

“十年之前&#xff0c;你不认识我&#xff0c;我不认识你&#xff0c;因为云计算我们携手并肩&#xff1b;十年之后&#xff0c;我们仍是伙伴&#xff0c;更是朋友&#xff0c;因为人工智能再次起程。”这就是今天的亚马逊云科技与其合作伙伴的真实写照。 2024年是亚马逊云科技…

STM8定时器

目录 一、定时器的工作原理 二、定时器功能的实现 &#xff08;a&#xff09;官方提供的定时器4的例程 &#xff08;b&#xff09;修改官方提供的例程&#xff0c;使其更加符合我们的需求 &#xff08;c&#xff09;代码分析 &#xff08;d&#xff09;代码汇总 三、利用…

Python24 机器学习之决策树

1.什么是机器学习&#xff1f; 机器学习是人工智能&#xff08;AI&#xff09;的一个分支&#xff0c;它使计算机系统能够从经验中学习并根据这些学习的数据做出决策或预测&#xff0c;而无需进行明确的编程。简而言之&#xff0c;机器学习涉及算法和统计模型的使用&#xff0…

ZNB40 矢量网络分析仪

ZNB40 矢量网络分析仪 100kHz至40GHz的宽频率范围&#xff0c;具有四个端口和附加信号发生器 概述 R&SZNB40 提供 100 kHz 至 40 GHz 的宽频率范围&#xff0c;具有四个端口和附加信号发生器。 罗德与施瓦茨带四个端口和附加内部信号源的 40 GHz 中档矢量网络分析仪&…

【C++题解】1715. 输出满足条件的整数5

问题&#xff1a;1715. 输出满足条件的整数5 类型&#xff1a;简单循环 题目描述&#xff1a; 有这样一个四位数,其千位和百位之和为偶数&#xff0c;十位和个位之和为奇数&#xff0c;且前两位之和大于后两位之和&#xff0c;且含有因数 8 &#xff0c;请输出满足上述条件的…

基于weixin小程序校园快递系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;订单管理&#xff0c;快递管理&#xff0c;快递记录管理&#xff0c;公告管理&#xff0c;基础数据管理 小程序功能包括&#xff1a;系统首页&#xff0c;…

【SSM】医疗健康平台-管理端-运营数据报表导出

知识目标 熟悉JasperReports的用法&#xff0c;能够使用JasperReports实现PDF文件导出 掌握Excel方式导出运营数据报表的方法&#xff0c;能够使用Apache POI以Excel方式导出运营数据报表 掌握PDF方式导出运营数据报表的方法&#xff0c;能够使用JasperReports以PDF方式导出运…

SpringCloud Alibaba Sentinel中@SentinelResource使用实践总结

Sentinel 提供了 SentinelResource 注解用于定义资源&#xff0c;并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。 注意&#xff1a;注解方式埋点不支持 private 方法。 官网地址&#xff1a;注解埋点支持 【1】资源名称限流 ① controller方法 GetMapp…

基于requests模块爬取网易云歌曲评论并制作热词云图(2024七月最新可用,超详细讲解,从零开始完成项目,python爬虫高分大作业)

本实践大作业要求 本次实践大作业主要要求主要包括&#xff1a; 1、选择一个热点或者你感兴趣的主题作为本次爬虫实践作业要完成的任务。 2、为了完成本次任务&#xff0c;需要确定从网上爬取的数据对象与范围。 3、利用python及网络爬虫相关技术实现从网上爬取相应内容数据。 …

煤安防爆手机为什么能在煤矿井下使用

煤安防爆手机之所以能在煤矿井下使用&#xff0c;是因为它们经过特殊设计&#xff0c;符合严格的防爆安全标准&#xff0c;能够防止电火花引发爆炸&#xff0c;同时具备防尘防水、抗冲击等特性&#xff0c;确保在恶劣的煤矿环境中稳定可靠地运行&#xff0c;为工作人员提供安全…

【JavaScript】一键入门

目录 一、JS起源 二、JS特点 三、JS组成部分 四、JS引入方式 一、JS起源 Java Script是由网景公司的Live Script发展而来的一种运行在客户端浏览器上的脚本语言&#xff0c;可以实现网页如文本内容、数据动态变化和动画特效等即浏览器与用户交互的这种体验。 二、JS特点 …

【Java Web】三大域对象

目录 一、域对象概述 二、三大域对象 三、域对象使用相关API 一、域对象概述 一些可用于存储数据和传递数据的对象被称为域对象&#xff0c;根据传递数据范围的不同&#xff0c;我们称之为不同的域&#xff0c;不同的域对象代表不同的域&#xff0c;共享数据的范围也不同。 二、…

更难、更好、更快、更强:LLM Leaderboard v2 现已发布

评估和比较大语言模型 (LLMs) 是一项艰巨的任务。我们 RLHF 团队在一年前就意识到了这一点&#xff0c;当时他们试图复现和比较多个已发布模型的结果。这几乎是不可能完成的任务&#xff1a;论文或营销发布中的得分缺乏可复现的代码&#xff0c;有时令人怀疑&#xff0c;大多数…