【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染
一、环境说明
-
DevEco Studio 版本:
-
API版本:以12为主
二、调用后台接口及List组件渲染
-
后台接口及返回数据分析
JSON数据格式如下:
json{ "code": 0, "data": { "total": 6, "pageSize": 10, "totalPage": 1, "currPage": 1, "list": [ { "id": 31, "biaoti": "标题1", "neirong": "内容1", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人1", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian1.jpg", "thumbsupnum": 1, "crazilynum": 1, "clicktime": "2024-08-05 12:00:04", "clicknum": 4, "addtime": "2024-08-05 11:59:29" }, { "id": 32, "biaoti": "标题2", "neirong": "内容2", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人2", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian2.jpg", "thumbsupnum": 2, "crazilynum": 2, "clicktime": "2024-08-05 12:00:04", "clicknum": 5, "addtime": "2024-08-05 11:59:29" }, { "id": 33, "biaoti": "标题3", "neirong": "内容3", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人3", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian3.jpg", "thumbsupnum": 3, "crazilynum": 3, "clicktime": "2024-08-05 12:00:04", "clicknum": 3, "addtime": "2024-08-05 11:59:29" }, { "id": 34, "biaoti": "标题4", "neirong": "内容4", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人4", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian4.jpg", "thumbsupnum": 4, "crazilynum": 4, "clicktime": "2024-08-05 12:01:05", "clicknum": 7, "addtime": "2024-08-05 11:59:29" }, { "id": 35, "biaoti": "标题5", "neirong": "内容5", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人5", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian5.jpg", "thumbsupnum": 5, "crazilynum": 5, "clicktime": "2024-08-05 12:00:04", "clicknum": 5, "addtime": "2024-08-05 11:59:29" }, { "id": 36, "biaoti": "标题6", "neirong": "<p>66232</p>", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人6", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian6.jpg", "thumbsupnum": 6, "crazilynum": 6, "clicktime": "2024-08-05 12:00:50", "clicknum": 12, "addtime": "2024-08-05 11:59:29" } ] } }
-
新建后台数据相关的实体类
新建common目录并在其下新建bean目录,然后在bean目录下新建
NewsDataItem.ets
类,用于封装整个后台JSON数据的最内层数据
:typescript/** * 用于定义具体的数据项 * { "id": 31, "biaoti": "标题1", "neirong": "内容1", "shipin": "", "fabushijian": "2024-08-05 11:59:42", "faburen": "发布人1", "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian1.jpg", "thumbsupnum": 1, "crazilynum": 1, "clicktime": "2024-08-05 12:00:04", "clicknum": 4, "addtime": "2024-08-05 11:59:29" } */ export default class NewsDataItem { public id: number public biaoti: string public neirong: string public shipin: string public fabushijian: string public faburen: string public fengmian: string // API12的语法,如果构造函数中该属性作为形式参数且是可选参数时,要保持类型一致 public thumbsupnum: number public crazilynum: number public clicktime: string public clicknum: number public addtime: string /** * 构造函数 * @param id * @param biaoti * @param neirong * @param shipin * @param fabushijian * @param faburen * @param fengmian * @param thumbsupnum * @param crazilynum * @param clicktime * @param clicknum * @param addtime */ constructor(id: number, biaoti: string, neirong: string, shipin: string, fabushijian: string, faburen: string, fengmian: string, thumbsupnum: number, crazilynum: number, clicktime: string, clicknum: number, addtime: string) { this.id = id this.biaoti = biaoti this.neirong = neirong this.shipin = shipin this.fabushijian = fabushijian this.faburen = faburen this.fengmian = fengmian this.thumbsupnum = thumbsupnum this.crazilynum = crazilynum this.clicktime = clicktime this.clicknum = clicknum this.addtime = addtime } }
然后在bean目录下新建
NewsData.ets
类,用于封装整个后台JSON数据的中间层数据
:typescript/** * 定义用于接收后台返回的json中间层数据 * "data": { "total": 6, "pageSize": 10, "totalPage": 1, "currPage": 1, "list": [] */ import NewsDataItem from './NewsDataItem' export default class NewsData{ public total: number public pageSize: number public totalPage: number public currPage: number public list: Array<NewsDataItem> constructor(total: number, pageSize: number, totalPage: number, currPage: number, list: Array<NewsDataItem>) { this.total = total this.pageSize = pageSize this.totalPage = totalPage this.currPage = currPage this.list = list } }
然后在bean目录下新建
NewsResultData.ets
类,用于封装整个后台JSON数据的最外层数据
:typescript/** * 定义用于接收后台返回的json最外层数据 * { * code: 0, * data: {} * } */ import NewsData from './NewsData'; export default class NewsResultData extends Object{ public code: number; public data: NewsData; constructor(code: number,data: NewsData) { super(); this.code = code; this.data = data; } }
-
新建ListComponentPage.ets页面,实现aboutToAppear()函数,然后在该函数中调用后台接口,最后用List组件渲染后台数据,具体代码如下:
typescriptimport NewsDataItem from '../common/bean/NewsDataItem' import { http } from '@kit.NetworkKit'; import NewsResultData from '../common/bean/NewsResultData'; import NewsData from '../common/bean/NewsData'; @Preview @Entry @Component struct ListComponentPage { private httpReq = http.createHttp() @State listData: Array<NewsDataItem> = [] aboutToAppear(): void { // 调用接口 this.httpReq.request('http://localhost:8080/springboot/xinwen/list').then((resp) => { //console.info("---调用后台接口返回---", JSON.stringify(resp)) if (resp !== undefined && resp !== null) { if (resp.responseCode == 200) { //console.info("---resp.result---", resp.result) let newsResult: NewsResultData = JSON.parse(resp.result.toString()) //console.info("---newsData---", newsResult.code) if (newsResult !== undefined && resp !== null) { let newsData: NewsData = newsResult.data this.listData = newsData.list } } } }).catch((reason: object) => { console.info("---接口错误信息---", JSON.stringify(reason)) }) } build() { Column() { List({ space: 10 }) { ForEach(this.listData, (item: NewsDataItem) => { ListItem() { Text(`${item.biaoti}`) .width('100%') .height(100) .fontSize(20) .fontColor(Color.White) .textAlign(TextAlign.Center) .borderRadius(10) .backgroundColor(0x007DFF) } }) } // 分割线 .divider({ strokeWidth: 5, color: Color.Red, startMargin: 10, endMargin: 10 }) // 设置成水平方向 // .listDirection(Axis.Horizontal) // 滑动事件 .onScrollIndex((firstIndex: number, lastIndex: number) => { console.info('滑动起始位置索引值' + firstIndex) console.info('滑动结束位置索引值' + lastIndex) }) .onDidScroll((scrollOffset: number, scrollState: ScrollState) => { console.info('滑动偏移量' + scrollOffset) console.info('当前滑动状态' + scrollState) }) .onReachStart(() => { console.info('列表起始位置到达') }) .onReachEnd(() => { console.info('列表末尾位置到达') }) .onScrollStop(() => { console.info('列表滑动停止') }) } .padding(12) .height('100%') .backgroundColor(0xF1F3F5) } }
-
重新编译,运行效果如下:
三、总结
有如下关键几点:
- 调用后台接口,需要引入http模块或者其他诸如Ajax、axios等网络请求模块;
- 如果是需要在页面被创建的时候调用后台接口,则需要在aboutToAppear()中进行调用,如需要在页面显示时需要调用后台接口加载数据,则可以在onPageShow()函数中进行调用。根据实际业务结合组件的生命周期进行合适的调用;
- 如使用JSON.parse报错Structural typing is not supported (arkts-no-structural-typing),其原因是引入
import { JSON } from '@kit.ArkTS';
模块中的JSON,需要将其删除掉,使用内置的JSON对象(不需要显示引用);