【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.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

  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华三交换机的软件版本升级操作

升级操作很常见&#xff0c;掌握方法是关键 实验环境&#xff1a;1台华三S6520-EI交换机&#xff0c;版本从2432P03升级成2432P05。 整体思路&#xff1a; 1.先查验软件版本 2.官网下载对于设备型号的软件版本 3.配置交换机地址使得与电脑进行通信&#xff0c;使用TFTP/FTP工…

宿主机无法通过ip连接wsl2解决方案

文章目录 原因排查网络模式win11防火墙关闭wsl ubuntu防火墙 如果之前能连接现在连接不上可以参考该方案 原因排查 网络模式win11防火墙(win11新增了Hyper-V防火墙)wsl2 ubuntu防火墙 网络模式 wsl2的默认网络模式是NAT&#xff0c;建议修改为镜像模式。在C:\Users\<User…

深圳,不止是“搞钱之都”

深圳又结结实实火了一把。 “建议深圳人吃饭不要谈工作”&#xff0c;这条微博话题热度飙升&#xff0c;超过五百多万人围观&#xff0c;引来无数网友吐槽“深圳人饭局的真实写照”。 从高档粤菜包间到路边小摊&#xff0c;从茶餐厅到烧烤摊&#xff0c;深圳人吃饭似乎总绕不…

Objects and Classes (对象和类)

Objects and Classes [对象和类] 1. Procedural and Object-Oriented Programming (过程性编程和面向对象编程)2. Abstraction and Classes (抽象和类)2.1. Classes in C (C 中的类)2.2. Implementing Class Member Functions (实现类成员函数)2.3. Using Classes References O…

华为---VRRP基本配置(一)

10、VRRP 10.1 VRRP基本配置 10.1.1 原理概述 随着Internet的发展&#xff0c;人们对网络可靠性的要求越来越高。对于用户来说&#xff0c;能够时刻与外部网络保持通信非常重要&#xff0c;但内部网络中的所有主机通常只能设置一个网关IP地址&#xff0c;通过该出口网关实现…

前端打包配置+nginx配置实现部署及部署地址带特定前缀的几种方式

前端打包后要部署到服务器&#xff0c;在浏览器中可以通过url访问到我们开发的系统&#xff0c;通过nginx代理在工作中是一种很常用的方式。 这里以本地为例&#xff0c;把本地电脑当作一个服务器&#xff0c;实现普通部署、带特定前缀等 前端使用vue-clivue作为例子 以下内容…

电脑突然提示dll文件丢失,怎么选择正确的恢复方法?

电脑突然提示dll文件丢失&#xff1f;其实当你的电脑使用久了&#xff0c;出现这种dll文件丢失是非常的正常的&#xff0c;毕竟你总会有不恰当的操作吧&#xff1f;这些操作都是会导致dll文件丢失的。丢失了&#xff0c;我们直接进行相关的修复就好了&#xff0c;还是比较简单的…

Qt开发 | Qt控件 | QTabWidget基本用法 | QListWidget应用详解 | QScrollArea应用详解

文章目录 一、QTabWidget基本用法二、QListWidget应用详解1.列表模式1.1 基本操作1.2 添加自定义item1.3 如何添加右键菜单1.4 QListWidget如何删除item 2.图标模式 三、QScrollArea应用详解 一、QTabWidget基本用法 QTabWidget 是 Qt 框架中的一个类&#xff0c;它提供了一个选…

C++学习/复习18----迭代器/反向迭代器及在list/vector中的应用、list与vector模拟实现复习

迭代器是一个对象&#xff0c;可以循环访问 C 标准库容器中的元素&#xff0c;并提供对各个元素的访问。 C 标准库容器全都提供迭代器&#xff0c;以便算法可以采用标准方式访问其元素&#xff0c;而不必考虑用于存储元素的容器类型。 一、反向迭代器类 基于普通迭代器构建反…

【Chapter8】文件系统,计算机操作系统教程,第四版,左万利,王英

文章目录 [toc]一、文件与文件系统1.1 文件1.2 文件系统 二、文件的访问方式2.1 顺序访问2.2 随机访问 三、文件的组织3.1 文件的逻辑组织3.2 文件的物理组织3.2.1 顺序结构3.2.2 链接结构3.2.3 索引结构3.2.4 Hash 结构3.2.5 倒排结构 3.3 UNIX文件物理结构&#xff08;索引链…

HarmonyOS Next开发学习手册——进程模型线程模型

进程模型 系统的进程模型如下图所示&#xff1a; 应用中&#xff08;同一包名&#xff09;的所有PageAbility、ServiceAbility、DataAbility、FormAbility运行在同一个独立进程中&#xff0c;即图中绿色部分的“Main Process”。 WebView拥有独立的渲染进程&#xff0c;即图中…

智能工厂中滑环应用的集成式和分立式数据接口解决方案

第四次工业革命通过在生产过程中实现新场景来推动数字化制造向前发展。这些场景依赖于基本的设计原则&#xff0c;包括器件互联、信息透明、技术协助&#xff0c;以及分散决策。没有先进的无线通信技术&#xff0c;就无法在现代智能工厂中实现所有这些原则。它们支持在广泛的领…

JM日志文件解析

研究意义 JM代码是对H264协议支持最全面的,不但还有编码还包括解码,通过它生成的trace文件可以对码流做一个很好的解读,目前很多码流分析工具也是基于JM的trace文件进行分析,研究它可以更深刻的理解H264协议。 环境搭建 先用cmake.exe 生成VS的工程文件 ●用VS 2019编译…

Modbus TCP什么场景用?

什么是Modbus TCP Modbus TCP是一种基于TCP/IP网络的通信协议&#xff0c;它允许不同的设备通过以太网进行数据交换。Modbus协议最初是为串行通信设计的&#xff0c;但随着网络技术的发展&#xff0c;Modbus TCP应运而生&#xff0c;它继承了Modbus RTU和Modbus ASCII的许多优点…

【分布式文件系统HDFS】文件操作基本命令的使用

目录 一、按照下述要求写出相应的文件操作命令&#xff0c;执行并观察结果 1. 新建目录 1.1 在本地文件系统按要求创建如下的文件夹 1.2 在HDFS文件系统按要求创建如下的文件夹 2. 编辑文件test1.txt&#xff0c;放入本地文件夹 /opt/user/myfile 3. 使用moveFromLocal命令…

沙盒在数据防泄密领域意义

在信息化快速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据泄密事件频发&#xff0c;给企业的安全和发展带来了巨大威胁。SDC沙盒防泄密系统&#xff0c;作为一种创新的数据防泄密解决方案&#xff0c;正逐渐在数据防泄密领域发挥着越来越重要的…

客户端输入网址后发生的全过程解析(协议交互、缓存、渲染)

目录 1. 输入 URL 并按下回车键2. DNS 解析3. TCP 连接4. 发送 HTTP 请求5. 服务器处理请求6. 发送 HTTP 响应7. 浏览器接收响应8. 渲染网页9. 执行脚本10. 处理其他资源11. TLS/SSL 加密&#xff08;如果使用 HTTPS&#xff09;握手过程 12. 协议协商和优化 总结 1. 输入 URL …

低碳短视频:成都柏煜文化传媒有限公司

低碳短视频&#xff1a;绿色传播的新风尚 随着全球气候变化和环境问题日益严峻&#xff0c;低碳生活已经成为人们追求的新风尚。在这个背景下&#xff0c;低碳短视频应运而生&#xff0c;以其独特的方式传播绿色理念&#xff0c;推动低碳生活方式的普及。成都柏煜文化传媒有限…

如何使用sr2t将你的安全扫描报告转换为表格格式

关于sr2t sr2t是一款针对安全扫描报告的格式转换工具&#xff0c;全称为“Scanning reports to tabular”&#xff0c;该工具可以获取扫描工具的输出文件&#xff0c;并将文件数据转换为表格格式&#xff0c;例如CSV、XLSX或文本表格等&#xff0c;能够为广大研究人员提供一个…

boss直聘招聘数据可视化分析

boss直聘招聘数据可视化分析 一、数据预处理二、数据可视化三、完整代码一、数据预处理 在 上一篇博客中,笔者已经详细介绍了使用selenium爬取南昌市web前端工程师的招聘岗位数据,数据格式如下: 这里主要对薪水列进行处理,为方便处理,将日薪和周薪的数据删除,将带有13薪…