§ 页面逻辑处理

本文配套视频地址:

https://v.qq.com/x/page/n0554dndrez.html


开始前请把 ch3-2 分支中的 code/ 目录导入微信开发工具

修改 index.js 文件,引入我们需要的外部资源

  1. 'use strict';
  2. import util from '../../utils/index';
  3. import config from '../../utils/config';
  4. let app = getApp();
  5. let isDEV = config.isDev;
  6. // 后继的代码都会放在此对象中
  7. let handler = {
  8. }
  9. Page(handler)

数据绑定

我们首先挖出和渲染相关的数据,并添加在 handler 对象的 data 字段中(Model 层)

修改 index.js 中的 handler 对象:

  1. // 此处省略部分代码
  2. let handler = {
  3. data: {
  4. page: 1, //当前加载第几页的数据
  5. days: 3,
  6. pageSize: 4,
  7. totalSize: 0,
  8. hasMore: true,// 用来判断下拉加载更多内容操作
  9. articleList: [], // 存放文章列表数据,与视图相关联
  10. defaultImg: config.defaultImg
  11. },
  12. }

注意: 后续添加的代码都是放在 handler 对象中,它会传递到 Page 函数中用来初始化页面组件

获取数据

然后要做的就是获取列表的数据,初始化数据的工作我们一般放在生命周期的 onLoad() 里:

  1. let handler = {
  2. onLoad (options) {
  3. this.requestArticle()
  4. },
  5. /*
  6. * 获取文章列表数据
  7. */
  8. requestArticle () {
  9. util.request({
  10. url: 'list',
  11. mock: true,
  12. data: {
  13. tag:'微信热门',
  14. start: this.data.page || 1,
  15. days: this.data.days || 3,
  16. pageSize: this.data.pageSize,
  17. langs: config.appLang || 'en'
  18. }
  19. })
  20. .then(res => {
  21. console.log( res )
  22. });
  23. }
  24. }

数据加载完成之后,我们需要对接口返回的数据进行业务方面的容错处理

修改 requestArticle 函数:

  1. let handler = {
  2. // 此处省略部分代码
  3. requestArticle () {
  4. util.request({
  5. url: 'list',
  6. mock: true,
  7. data: {
  8. tag:'微信热门',
  9. start: this.data.page || 1,
  10. days: this.data.days || 3,
  11. pageSize: this.data.pageSize,
  12. langs: config.appLang || 'en'
  13. }
  14. })
  15. .then(res => {
  16. // 数据正常返回
  17. if (res && res.status === 0 && res.data && res.data.length) {
  18. // 正常数据 do something
  19. console.log(res)
  20. }
  21. /*
  22. * 如果加载第一页就没有数据,说明数据存在异常情况
  23. * 处理方式:弹出异常提示信息(默认提示信息)并设置下拉加载功能不可用
  24. */
  25. else if (this.data.page === 1 && res.data && res.data.length === 0) {
  26. util.alert();
  27. this.setData({
  28. hasMore: false
  29. });
  30. }
  31. /*
  32. * 如果非第一页没有数据,那说明没有数据了,停用下拉加载功能即可
  33. */
  34. else if (this.data.page !== 1 && res.data && res.data.length === 0) {
  35. this.setData({
  36. hasMore: false
  37. });
  38. }
  39. /*
  40. * 返回异常错误
  41. * 展示后端返回的错误信息,并设置下拉加载功能不可用
  42. */
  43. else {
  44. util.alert('提示', res);
  45. this.setData({
  46. hasMore: false
  47. });
  48. return null;
  49. }
  50. })
  51. }
  52. }

上面我们把 wx.request 重新包装成了 Promise 的形式,其实我们是请求的 mock 数据。但是接口请求到的数据绝大部分情况下都不会直接适用于 UI 展示,所以我们需要做一层数据转换,把接口数据转换成视图数据。

格式化数据

先看下后端返回的数据结构

我们需要做两件事情

  1. 遍历 data 数组,对返回的日期格式化,当天的显示 今天,如果是今年的文章,显示月日格式 08-21 ;如果是往年的文章,显示标准的年月日格式 2015-06-12
  2. 遍历 articles 数组,判断此篇文章的 contentId 是否已经在全局变量 visitedArticles 中,如果存在,说明已经访问过。

修改 app.js,增加全局变量 visitedArticles

  1. globalData: {
  2. user: {
  3. name: '',
  4. avator: ''
  5. },
  6. visitedArticles: ''
  7. }

修改 index.js 中的 requestArticle 函数:

  1. let handler = {
  2. // 此处省略部分代码
  3. requestArticle () {
  4. // 注意:修改此处代码
  5. if (res && res.status === 0 && res.data && res.data.length) {
  6. let articleData = res.data;
  7. //格式化原始数据
  8. let formatData = this.formatArticleData(articleData);
  9. console.log( formatData )
  10. }
  11. }
  12. }

增加对列表数据格式化的代码:

  1. let handler = {
  2. // 此处省略部分代码
  3. /*
  4. * 格式化文章列表数据
  5. */
  6. formatArticleData (data) {
  7. let formatData = undefined;
  8. if (data && data.length) {
  9. formatData = data.map((group) => {
  10. // 格式化日期
  11. group.formateDate = this.dateConvert(group.date);
  12. if (group && group.articles) {
  13. let formatArticleItems = group.articles.map((item) => {
  14. // 判断是否已经访问过
  15. item.hasVisited = this.isVisited(item.contentId);
  16. return item;
  17. }) || [];
  18. group.articles = formatArticleItems;
  19. }
  20. return group
  21. })
  22. }
  23. return formatData;
  24. },
  25. /*
  26. * 将原始日期字符串格式化 '2017-06-12'
  27. * return '今日' / 08-21 / 2017-06-12
  28. */
  29. dateConvert (dateStr) {
  30. if (!dateStr) {
  31. return '';
  32. }
  33. let today = new Date(),
  34. todayYear = today.getFullYear(),
  35. todayMonth = ('0' + (today.getMonth() + 1)).slice(-2),
  36. todayDay = ('0' + today.getDate()).slice(-2);
  37. let convertStr = '';
  38. let originYear = +dateStr.slice(0,4);
  39. let todayFormat = `${todayYear}-${todayMonth}-${todayDay}`;
  40. if (dateStr === todayFormat) {
  41. convertStr = '今日';
  42. } else if (originYear < todayYear) {
  43. let splitStr = dateStr.split('-');
  44. convertStr = `${splitStr[0]}年${splitStr[1]}月${splitStr[2]}日`;
  45. } else {
  46. convertStr = dateStr.slice(5).replace('-', '月') + '日'
  47. }
  48. return convertStr;
  49. },
  50. /*
  51. * 判断文章是否访问过
  52. * @param contentId
  53. */
  54. isVisited (contentId) {
  55. let visitedArticles = app.globalData && app.globalData.visitedArticles || '';
  56. return visitedArticles.indexOf(`${contentId}`) > -1;
  57. },
  58. }

正常情况下,这个时候控制台打印出来的数据,是经过格式化的标准数据了,下一步,我们需要把它添加到 data 中的 articleList 字段里面,这样视图才有了渲染的数据

修改 index.js,增加 renderArticle 函数。由于每次请求的都是某一页的数据,所以在函数中,我们需要把每次请求过来的列表数据都 concat(拼接)到 articleList中:

  1. let handler = {
  2. // 此处省略部分代码
  3. renderArticle (data) {
  4. if (data && data.length) {
  5. let newList = this.data.articleList.concat(data);
  6. this.setData({
  7. articleList: newList
  8. })
  9. }
  10. }
  11. }

requestArticle 函数中调用 renderArticle:

  1. let handler = {
  2. // 此处省略部分代码
  3. requestArticle () {
  4. // 注意:修改此处代码
  5. if (res && res.status === 0 && res.data && res.data.length) {
  6. let articleData = res.data;
  7. //格式化原始数据
  8. let formatData = this.formatArticleData(articleData);
  9. this.renderArticle( formatData )
  10. }
  11. }
  12. }

最终结果

最终的 index.js 文件就是这样的:

  1. 'use strict';
  2. import util from '../../utils/index'
  3. import config from '../../utils/config'
  4. let app = getApp()
  5. let isDEV = config.isDev
  6. // 后继的代码都会放在此对象中
  7. let handler = {
  8. data: {
  9. page: 1, //当前的页数
  10. days: 3,
  11. pageSize: 4,
  12. totalSize: 0,
  13. hasMore: true,// 用来判断下拉加载更多内容操作
  14. articleList: [], // 存放文章列表数据
  15. defaultImg: config.defaultImg
  16. },
  17. onLoad(options) {
  18. this.requestArticle();
  19. },
  20. /*
  21. * 获取文章列表数据
  22. */
  23. requestArticle() {
  24. util.request({
  25. url: 'list',
  26. mock: true,
  27. data: {
  28. tag: '微信热门',
  29. start: this.data.page || 1,
  30. days: this.data.days || 3,
  31. pageSize: this.data.pageSize,
  32. langs: config.appLang || 'en'
  33. }
  34. })
  35. .then(res => {
  36. // 数据正常返回
  37. if (res && res.status === 0 && res.data && res.data.length) {
  38. let articleData = res.data;
  39. //格式化原始数据
  40. let formatData = this.formatArticleData(articleData);
  41. this.renderArticle(formatData)
  42. }
  43. /*
  44. * 如果加载第一页就没有数据,说明数据存在异常情况
  45. * 处理方式:弹出异常提示信息(默认提示信息)并设置下拉加载功能不可用
  46. */
  47. else if (this.data.page === 1 && res.data && res.data.length === 0) {
  48. util.alert();
  49. this.setData({
  50. hasMore: false
  51. });
  52. }
  53. /*
  54. * 如果非第一页没有数据,那说明没有数据了,停用下拉加载功能即可
  55. */
  56. else if (this.data.page !== 1 && res.data && res.data.length === 0) {
  57. this.setData({
  58. hasMore: false
  59. });
  60. }
  61. /*
  62. * 返回异常错误
  63. * 展示后端返回的错误信息,并设置下拉加载功能不可用
  64. */
  65. else {
  66. util.alert('提示', res);
  67. this.setData({
  68. hasMore: false
  69. });
  70. return null;
  71. }
  72. })
  73. },
  74. /*
  75. * 格式化文章列表数据
  76. */
  77. formatArticleData(data) {
  78. let formatData = undefined;
  79. if (data && data.length) {
  80. formatData = data.map((group) => {
  81. // 格式化日期
  82. group.formateDate = this.dateConvert(group.date);
  83. if (group && group.articles) {
  84. let formatArticleItems = group.articles.map((item) => {
  85. // 判断是否已经访问过
  86. item.hasVisited = this.isVisited(item.contentId);
  87. return item;
  88. }) || [];
  89. group.articles = formatArticleItems;
  90. }
  91. return group
  92. })
  93. }
  94. return formatData;
  95. },
  96. /*
  97. * 将原始日期字符串格式化 '2017-06-12'
  98. * return '今日' / 08-21 / 2017-06-12
  99. */
  100. dateConvert(dateStr) {
  101. if (!dateStr) {
  102. return '';
  103. }
  104. let today = new Date(),
  105. todayYear = today.getFullYear(),
  106. todayMonth = ('0' + (today.getMonth() + 1)).slice(-2),
  107. todayDay = ('0' + today.getDate()).slice(-2);
  108. let convertStr = '';
  109. let originYear = +dateStr.slice(0, 4);
  110. let todayFormat = `${todayYear}-${todayMonth}-${todayDay}`;
  111. if (dateStr === todayFormat) {
  112. convertStr = '今日';
  113. } else if (originYear < todayYear) {
  114. let splitStr = dateStr.split('-');
  115. convertStr = `${splitStr[0]}年${splitStr[1]}月${splitStr[2]}日`;
  116. } else {
  117. convertStr = dateStr.slice(5).replace('-', '月') + '日'
  118. }
  119. return convertStr;
  120. },
  121. /*
  122. * 判断文章是否访问过
  123. * @param contentId
  124. */
  125. isVisited(contentId) {
  126. let visitedArticles = app.globalData && app.globalData.visitedArticles || '';
  127. return visitedArticles.indexOf(`${contentId}`) > -1;
  128. },
  129. renderArticle(data) {
  130. if (data && data.length) {
  131. let newList = this.data.articleList.concat(data);
  132. this.setData({
  133. articleList: newList
  134. })
  135. }
  136. }
  137. }
  138. Page(handler)

下一篇中,我们将会把数据与视图层结合在一起,动态的展示视图层

iKcamp官网:http://www.ikcamp.com

访问官网更快阅读全部免费分享课程:《iKcamp出品|全网最新|微信小程序|基于最新版1.0开发者工具之初中级培训教程分享》。

包含:文章、视频、源代码

iKcamp原创新书《移动Web前端高效开发实战》已在亚马逊、京东、当当开售。

iKcamp最新活动

报名地址:http://www.huodongxing.com/event/5409924174200

“天天练口语”小程序总榜排名第四、教育类排名第一的研发团队,面对面沟通交流。

微信小程序教学第三章(含视频):小程序中级实战教程:列表-页面逻辑处理的更多相关文章

  1. 微信小程序教学第二章:小程序中级实战教程之预备篇 - 项目结构设计 |基于最新版1.0开发者工具

    iKcamp官网:http://www.ikcamp.com 访问官网更快阅读全部免费分享课程:<iKcamp出品|全网最新|微信小程序|基于最新版1.0开发者工具之初中级培训教程分享>. ...

  2. 微信小程序教学第三章第四节(含视频):小程序中级实战教程:下拉更新、分享、阅读标识

    下拉更新.分享.阅读标识 本文配套视频地址: https://v.qq.com/x/page/h0554i4u5ob.html 开始前请把 ch3-4 分支中的 code/ 目录导入微信开发工具 这一 ...

  3. 微信小程序教学第三章第三节(含视频):小程序中级实战教程:视图与数据关联

    § 视图与数据关联 本文配套视频地址: https://v.qq.com/x/page/z0554wyswib.html 开始前请把 ch3-3 分支中的 code/ 目录导入微信开发工具 首先 首先 ...

  4. 微信小程序教学第四章第三节(含视频):小程序中级实战教程:详情-功能完善

    详情 - 功能完善 本文配套视频地址: https://v.qq.com/x/page/f0555nfdi14.html 开始前请把 ch4-3 分支中的 code/ 目录导入微信开发工具 这一节中, ...

  5. 微信小程序教学第四章第一节(含视频):小程序中级实战教程:详情-页面制作

    详情 - 页面制作 本文配套视频地址: https://v.qq.com/x/page/o0555o20xjd.html 开始前请把 ch4-1 分支中的 code/ 目录导入微信开发工具 这一章节中 ...

  6. 微信小程序教学第四章第二节(含视频):小程序中级实战教程:详情-视图渲染

    § 详情 - 数据渲染 本文配套视频地址: https://v.qq.com/x/page/x055550lrvd.html 开始前请把 ch4-2 分支中的 code/ 目录导入微信开发工具 这一节 ...

  7. 微信小程序教学第二章(含视频):小程序中级实战教程之预备篇 - 封装网络请求及 mock 数据

    § 封装网络请求及 mock 数据 本文配套视频地址: https://v.qq.com/x/page/i05544fogcm.html 开始前请把 ch2-3 分支中的 code/ 目录导入微信开发 ...

  8. java中的数据类型,运算符,字符串,输入输出,控制流,大数值,数组; 《java核心技术卷i》 第三章:java基本程序结构;

    <java核心技术卷i> 第三章:java基本程序结构: 每次看书,去总结的时候,总会发现一些新的东西,这次对于java的数组有了更深的了解: java中的数据类型,运算符,字符串,输入输 ...

  9. 【WePY小程序框架实战二】-页面结构

    [WePY小程序框架实战一]-创建项目 项目结构 |-- dist |-- node_modules |-- src | |-- components |-- a.wpy |-- b.wpy |-- ...

随机推荐

  1. Android 之旅开始了!先自我了解下Android与Linux之间的关系

    Android是在Linux2.6的内核基础之上运行的,提供核心系统服务:安全.内存管理.进程管理.网络组.驱动模型.内核部分还相当于一个介于硬件层和系统中其他软件组之间的一个抽象层次.但是严格来说它 ...

  2. vpn服务器搭建

    这里我们用CentOS6.0和Shdowsocks搭建 首先了解几个命令 wget 是一个从网络上自动下载文件的自由工具,支持通过 HTTP.HTTPS.FTP 三个最常见的 TCP/IP协议 下载, ...

  3. KMP - LeetCode #459 Repeated Substring Pattern

    复习一下KMP算法 KMP的主要思想是利用字符串自身的前缀后缀的对称性,来构建next数组,从而实现用接近O(N)的时间复杂度完成字符串的匹配 对于一个字符串str,next[j] = k 表示满足s ...

  4. Java日志框架那些事儿

    文章首发于[博客园-陈树义],点击跳转到原文Java日志框架那些事儿. 在项目开发过程中,我们可以通过 debug 查找问题.而在线上环境我们查找问题只能通过打印日志的方式查找问题.因此对于一个项目而 ...

  5. Java爬虫框架WebMagic——入门(爬取列表类网站文章)

    初学爬虫,WebMagic作为一个Java开发的爬虫框架很容易上手,下面就通过一个简单的小例子来看一下. WebMagic框架简介 WebMagic框架包含四个组件,PageProcessor.Sch ...

  6. (转载)java 枚举 循环遍历以及一些简单常见的使用

    本文转载自:http://blog.csdn.net/qq_27093465/article/details/51706076 作者:李学凯 什么时候想用枚举类型: 有时候,在设计一个java mod ...

  7. 关于Unity里动态加载图片

    Resources.Load 使用该方法可以动态加载资源 过程: 1.首先需要在Project面板里创建一个名为Resources的文件夹(名字必须是这个 不能写错啊) 2.把要加载的游戏对象放到该目 ...

  8. Solr7 安装部署 管理界面介绍

    Solr7 安装部署 管理界面介绍 本章重点介绍CentOS 安装部署Solr7 ,Solr的管理界面介绍,添加核心Core配置,Dataimport导入数据,Documents 在线维护索引,Que ...

  9. Self Hosting WebServer 的几种方式

    写在前面: IIS是Windows平台非常关键的组件,它是微软自带的Web服务器,可以很方便的帮助我们运行起一个网站,WebApi等服务,提供给外部来访问.即使它被很多java或者ruby的同学各种鄙 ...

  10. liunx分布式监控工具

    监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的.你要确保用户始终可以打开你的网站并且网速不慢.服务器监控工具允许你收集和分析有关你的Web服务器的数据. 有许多非常好的服务器监控解决 ...