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

课程地址: 黑马程序员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.etsimport { 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.etsimport ShopInfo from '../viewmodel/ShopInfo'@Component
export default struct ShopItem {shop:ShopInfobuild() {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.tsimport http from '@ohos.net.http'
import ShopInfo from '../viewmodel/ShopInfo'class ShopModel{baseURL:string = 'localhost:3000'pageNo:number = 1getShopList(): 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.tsexport default class ShopInfo {id:numbername:string// @ts-ignoreimages:Resource[]area:stringaddress:stringavgPrice:numbercomments:numberscore:numberopenHours:string
}

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

// ShopPage.etsimport { 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 = falseisMore:boolean = trueaboutToAppear(){// 加载商品数据ShopModel.pageNo = 1this.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 = trueShopModel.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 = falseif(!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.mzph.cn/pingmian/35892.shtml

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

相关文章

深度之眼(二十五)——研究生学习计划安排

文章目录 一、前言二、结构安排和规划2.1 夯实基础2.2 分方向训练&#xff08;待&#xff09;2.3 进阶训练 三、其他 一、前言 课题组这边是需要对机器视觉有所要求吧&#xff0c;也就是CV方向。这一届研三师兄也都是在大厂拿到30W的年薪了&#xff0c;也是需要拥抱深度学习这…

java收徒 java辅导 java试用期辅导 java零基础学习

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末报名辅导&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还有大家…

守护变电箱消防安全,全氟己酮自动灭火片该安装在哪个位置?

变电箱、配电柜、换电柜是电力设备的重要组成部分&#xff0c;安全性至关重要。但在使用过程中&#xff0c;容易受到电气、机械、环境等因素影响&#xff0c;出现接触不良、短路、漏电等安全隐患&#xff0c;从而引发火灾事故。为了及时防范火灾风险&#xff0c;提前安装一款能…

Vue中数组的【响应式】操作

在 Vue.js 中&#xff0c;当你修改数组时&#xff0c;Vue 不能检测到以下变动的数组&#xff1a; 当你利用索引直接设置一个项时&#xff0c;例如&#xff1a;vm.items[indexOfItem] newValue当你修改数组的长度时&#xff0c;例如&#xff1a;vm.items.length newLength 为…

Java基础(二)——数组,方法,方法重载

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

01_02_Mybatis的配置文件与基于XML的使用

1、引入日志 在这里我们引入SLF4J的日志门面&#xff0c;使用logback的具体日志实现&#xff1b;引入相关依赖&#xff1a; <!--日志的依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version&g…

2024国内外音频转换器大盘点,盘点音乐剪辑的7个有效方法!

当遇到不支持的音乐文件时&#xff0c;您可能就会想要拥有一款优秀的音频转换器。当您想减小大量音乐文件以节省设备存储空间时&#xff0c;它也可以很好地帮上忙。如果您正在寻找这么一款音频转换器&#xff0c;那么&#xff0c;请不要错过这篇文章。一款顶尖的音频转换器不仅…

USB2.0学习1--基本概念

目录 1.USB概念 2.USB协议发展 3.USB接口类型 3.1 TYPE类型 3.2 Mini类型 3.3 Micro类型 4. USB体系结构和关键概念 4.1 USB工作原理 4.2 USB物理拓扑结构 4.3 USB逻辑拓扑结构 4.4 USB软件架构 4.5 USB数据流模型 4.5.1 USB设备端点 4.5.2 USB管道 4.6 USB即插…

网工内推 | 国企信息工程师,信息系统项目管理师优先,最高14薪

01 上海浦东软件园股份有限公司 &#x1f537;招聘岗位&#xff1a;信息化管理工程师 &#x1f537;岗位职责&#xff1a; 1. 根据公司战略、数字化总体架构规划和IT 技术趋势&#xff0c;制定信息化系统的规划与设计&#xff0c;并制定实施计划。 2. 统筹公司信息化系统管理…

Redis-实战篇-缓存击穿问题及解决方案

文章目录 1、缓存击穿2、常见的解决方案有两种&#xff1a;2.1、互斥锁2.2、逻辑过期2.3、两种方案对比 3、利用互斥锁解决缓存击穿问题3.1、ShopServiceImpl.java3.2、使用 jmeter.bat 测试高并发 4、利用逻辑过期解决缓存击穿问题 1、缓存击穿 缓存击穿问题 也叫 热点key问题…

<电力行业> - 《第4课:什么是电力?什么是发输变配用5环节?》

1 什么是电力&#xff1f; 我们对于平日生活中离不开的电很熟悉&#xff0c;但是电力是什么&#xff1f; 其实&#xff0c;电力就是电能作为动力的能源。电力就是我们说的电&#xff0c;不过更多了系统化。 19世纪70年代&#xff0c;电力的发明和应用掀起了第二次工业化高潮。…

关于WebSocket

WebSocket 与传统的 HTTP 协议对比 在实时通信领域&#xff0c;传统的 HTTP 协议存在以下一些问题&#xff1a; 频繁的请求和响应&#xff1a;每次通信都需要建立和关闭连接&#xff0c;带来额外的开销。高延迟&#xff1a;每次通信都需要经过多个网络层的传输&#xff0c;延…

Stm32的DMA的学习

一&#xff0c;介绍 二&#xff0c;DMA框图 三&#xff0c;DMA通道 四&#xff0c;相关HAL库函数 五&#xff0c;配置DMA 六&#xff0c;Stm32CubeMX配置 【13.1】减少CPU传输负载 DMA直接存储器访问—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili

【鸿蒙 HarmonyOS】尺寸设置:size/layoutWeight/constraintSize

一、背景 常见尺寸&#xff1a;width&#xff08;宽度&#xff09;、height&#xff08;高度&#xff09;、padding&#xff08;内边距&#xff09;、margin&#xff08;外边距&#xff09; 主要整理下size&#xff08;设置高宽尺寸&#xff09;、layoutWeight&#xff08;对…

Redis数据库(五):Redis数据库基本特性

这一节我们来介绍如何使用C语言的库来操作Redis数据库。 目录 一、hiredis的安装 1.1 下载源码 1.2 解压 1.3 进入hiredis路径下 1.4 利用makefile文件进行编译 二、接口介绍 三、C程序操作Redis代码 四、redis.conf配置文件详解 五、Redis的持久化 5.1 RDB &#x…

STM32CubeMX与RT-Thread Studio协助使用(实现点亮LED)

1创建自己的项目 1-1选择板子 1-2生成的项目 运行一下看是否创建成功 零警告零错误 2配置STM32Cude 2-1找打如图图标点击&#xff08;CubeMX的图标&#xff09; 2-2输入自己安装的路径选中exe文件 点击Browse 找到如图选中&#xff0c;在打开&#xff08;STM32CubeMX的安装路…

echarts 5.5.0版本下的层叠柱形图,每个值都从0开始,会有覆盖情况

需求&#xff1a; 1、每个公司&#xff0c;需要两个柱子去展示&#xff08;stack: 1是第一个柱子&#xff0c;stack:2,是第二个柱子&#xff09;&#xff1b; 2、必须每个数据都是从0开始&#xff0c;不在上一个值上累加&#xff1b; 3、鼠标滑上去的时候&#xff0c;最大值…

什么是API?如何进行API对接?

目录 一、API和API对接的定义 二、API接口的应用场景 三、为什么需要API对接 四、如何进行API对接 GET请求 POST请求 五、API对接的注意事项 在这个数字化时代&#xff0c;API像一把万能钥匙&#xff0c;让数据流动起来&#xff0c;创造出无限可能。本文旨在介绍API及其…

点云处理实战 PCL求解点云表面曲率

目录 一、什么是曲率 二、曲率计算过程 三、pcl 求解点云局部曲率 四、思考?为何曲率计算会使用协方差矩阵? 五、推荐阅读 一、什么是曲率 曲率是几何学中用来描述曲线或曲面形状变化的一个量。它反映了曲线或曲面的弯曲程度。在不同的上下文中,曲率的定义和计算方式有…

科普:什么是 BC-404 ?全方位解读最新通缩型 NFT 标准

区块链技术飞速发展的今天&#xff0c;创新从未停歇。继 ERC-404 标准问世后&#xff0c;一个名为 BC-404 的新标准应运而生&#xff0c;为 NFT 市场带来了全新的可能性。BC-404&#xff08;Bonding Curve 404&#xff09;—基于对 ERC-404 的改进&#xff0c;加密货币中第一个…