§ 页面逻辑处理

本文配套视频地址:

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


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

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

'use strict';

import util from '../../utils/index';
import config from '../../utils/config'; let app = getApp();
let isDEV = config.isDev; // 后继的代码都会放在此对象中
let handler = { }
Page(handler)

数据绑定

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

修改 index.js 中的 handler 对象:

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

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

获取数据

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

let handler = {
onLoad (options) {
this.requestArticle()
},
/*
* 获取文章列表数据
*/
requestArticle () {
util.request({
url: 'list',
mock: true,
data: {
tag:'微信热门',
start: this.data.page || 1,
days: this.data.days || 3,
pageSize: this.data.pageSize,
langs: config.appLang || 'en'
}
})
.then(res => {
console.log( res )
});
}
}

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

修改 requestArticle 函数:

let handler = {
// 此处省略部分代码
requestArticle () {
util.request({
url: 'list',
mock: true,
data: {
tag:'微信热门',
start: this.data.page || 1,
days: this.data.days || 3,
pageSize: this.data.pageSize,
langs: config.appLang || 'en'
}
})
.then(res => {
// 数据正常返回
if (res && res.status === 0 && res.data && res.data.length) {
// 正常数据 do something
console.log(res)
}
/*
* 如果加载第一页就没有数据,说明数据存在异常情况
* 处理方式:弹出异常提示信息(默认提示信息)并设置下拉加载功能不可用
*/
else if (this.data.page === 1 && res.data && res.data.length === 0) {
util.alert();
this.setData({
hasMore: false
});
}
/*
* 如果非第一页没有数据,那说明没有数据了,停用下拉加载功能即可
*/
else if (this.data.page !== 1 && res.data && res.data.length === 0) {
this.setData({
hasMore: false
});
}
/*
* 返回异常错误
* 展示后端返回的错误信息,并设置下拉加载功能不可用
*/
else {
util.alert('提示', res);
this.setData({
hasMore: false
});
return null;
}
})
}
}

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

格式化数据

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

我们需要做两件事情

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

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

globalData: {
user: {
name: '',
avator: ''
},
visitedArticles: ''
}

修改 index.js 中的 requestArticle 函数:

let handler = {
// 此处省略部分代码
requestArticle () {
// 注意:修改此处代码
if (res && res.status === 0 && res.data && res.data.length) {
let articleData = res.data;
//格式化原始数据
let formatData = this.formatArticleData(articleData);
console.log( formatData )
}
}
}

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

let handler = {
// 此处省略部分代码
/*
* 格式化文章列表数据
*/
formatArticleData (data) {
let formatData = undefined;
if (data && data.length) {
formatData = data.map((group) => {
// 格式化日期
group.formateDate = this.dateConvert(group.date);
if (group && group.articles) {
let formatArticleItems = group.articles.map((item) => {
// 判断是否已经访问过
item.hasVisited = this.isVisited(item.contentId);
return item;
}) || [];
group.articles = formatArticleItems;
}
return group
})
}
return formatData;
},
/*
* 将原始日期字符串格式化 '2017-06-12'
* return '今日' / 08-21 / 2017-06-12
*/
dateConvert (dateStr) {
if (!dateStr) {
return '';
}
let today = new Date(),
todayYear = today.getFullYear(),
todayMonth = ('0' + (today.getMonth() + 1)).slice(-2),
todayDay = ('0' + today.getDate()).slice(-2);
let convertStr = '';
let originYear = +dateStr.slice(0,4);
let todayFormat = `${todayYear}-${todayMonth}-${todayDay}`;
if (dateStr === todayFormat) {
convertStr = '今日';
} else if (originYear < todayYear) {
let splitStr = dateStr.split('-');
convertStr = `${splitStr[0]}年${splitStr[1]}月${splitStr[2]}日`;
} else {
convertStr = dateStr.slice(5).replace('-', '月') + '日'
}
return convertStr;
},
/*
* 判断文章是否访问过
* @param contentId
*/
isVisited (contentId) {
let visitedArticles = app.globalData && app.globalData.visitedArticles || '';
return visitedArticles.indexOf(`${contentId}`) > -1;
},
}

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

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

let handler = {
// 此处省略部分代码
renderArticle (data) {
if (data && data.length) {
let newList = this.data.articleList.concat(data);
this.setData({
articleList: newList
})
}
}
}

requestArticle 函数中调用 renderArticle:

let handler = {
// 此处省略部分代码
requestArticle () {
// 注意:修改此处代码
if (res && res.status === 0 && res.data && res.data.length) {
let articleData = res.data;
//格式化原始数据
let formatData = this.formatArticleData(articleData);
this.renderArticle( formatData )
}
}
}

最终结果

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

'use strict';

import util from '../../utils/index'
import config from '../../utils/config' let app = getApp()
let isDEV = config.isDev // 后继的代码都会放在此对象中
let handler = {
data: {
page: 1, //当前的页数
days: 3,
pageSize: 4,
totalSize: 0,
hasMore: true,// 用来判断下拉加载更多内容操作
articleList: [], // 存放文章列表数据
defaultImg: config.defaultImg
},
onLoad(options) {
this.requestArticle();
},
/*
* 获取文章列表数据
*/
requestArticle() {
util.request({
url: 'list',
mock: true,
data: {
tag: '微信热门',
start: this.data.page || 1,
days: this.data.days || 3,
pageSize: this.data.pageSize,
langs: config.appLang || 'en'
}
})
.then(res => {
// 数据正常返回
if (res && res.status === 0 && res.data && res.data.length) {
let articleData = res.data;
//格式化原始数据
let formatData = this.formatArticleData(articleData);
this.renderArticle(formatData)
}
/*
* 如果加载第一页就没有数据,说明数据存在异常情况
* 处理方式:弹出异常提示信息(默认提示信息)并设置下拉加载功能不可用
*/
else if (this.data.page === 1 && res.data && res.data.length === 0) {
util.alert();
this.setData({
hasMore: false
});
}
/*
* 如果非第一页没有数据,那说明没有数据了,停用下拉加载功能即可
*/
else if (this.data.page !== 1 && res.data && res.data.length === 0) {
this.setData({
hasMore: false
});
}
/*
* 返回异常错误
* 展示后端返回的错误信息,并设置下拉加载功能不可用
*/
else {
util.alert('提示', res);
this.setData({
hasMore: false
});
return null;
}
})
},
/*
* 格式化文章列表数据
*/
formatArticleData(data) {
let formatData = undefined;
if (data && data.length) {
formatData = data.map((group) => {
// 格式化日期
group.formateDate = this.dateConvert(group.date);
if (group && group.articles) {
let formatArticleItems = group.articles.map((item) => {
// 判断是否已经访问过
item.hasVisited = this.isVisited(item.contentId);
return item;
}) || [];
group.articles = formatArticleItems;
}
return group
})
}
return formatData;
},
/*
* 将原始日期字符串格式化 '2017-06-12'
* return '今日' / 08-21 / 2017-06-12
*/
dateConvert(dateStr) {
if (!dateStr) {
return '';
}
let today = new Date(),
todayYear = today.getFullYear(),
todayMonth = ('0' + (today.getMonth() + 1)).slice(-2),
todayDay = ('0' + today.getDate()).slice(-2);
let convertStr = '';
let originYear = +dateStr.slice(0, 4);
let todayFormat = `${todayYear}-${todayMonth}-${todayDay}`;
if (dateStr === todayFormat) {
convertStr = '今日';
} else if (originYear < todayYear) {
let splitStr = dateStr.split('-');
convertStr = `${splitStr[0]}年${splitStr[1]}月${splitStr[2]}日`;
} else {
convertStr = dateStr.slice(5).replace('-', '月') + '日'
}
return convertStr;
},
/*
* 判断文章是否访问过
* @param contentId
*/
isVisited(contentId) {
let visitedArticles = app.globalData && app.globalData.visitedArticles || '';
return visitedArticles.indexOf(`${contentId}`) > -1;
},
renderArticle(data) {
if (data && data.length) {
let newList = this.data.articleList.concat(data);
this.setData({
articleList: newList
})
}
}
}
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开发之漫漫长途 番外篇——自定义View的各种姿势1

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  2. em单位使用小结

    em是一个css的单位. em是一个相对的单位.相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸.(引自CSS2.0手册) 一般在DOM元素中,当前 ...

  3. 关于如何在微信里面让video不全屏播放

    发现一个更简单的解决方法,加上一条属性即可.x5-video-player-type="h5″.通过设置这个属性,让video开启同层H5播放器.另外在X5内核里,video是单独的一个vi ...

  4. Office 365系列 (1)概览:完整的云中Office

    Office365(以下简称O365)是一个集Office,企业邮箱,日历,日程管理,音视频会议 ,企业网盘 ,企业协作平台为一体的,旨在提高团队办公效率,减少基础设施投资和IT运维压力的解决方案.在 ...

  5. Resin4安装配置

    #Resin4安装配置 # Resin4安装配置 #centos6 #参考http://467754239.blog.51cto.com/4878013/1558435 #yum -y install ...

  6. linux上mysql安装与卸载

    以下步骤运行环境是centos6.5   1.查找以前是否装有mysql命令:rpm -qa|grep -i mysql2.删除mysql删除命令:rpm -e --nodeps 包名3.删除老版本m ...

  7. python 生成html文件(表格)

    import pandas as pd def convert_to_html(result,title): d = {} index = 0 for t in title: d[] = result ...

  8. 企业级Tomcat安全管理优化方案

    telnet管理端口保护 1. 修改默认的8005管理端口为不易猜测的端口(大于1024): <Server port=" shutdown="dangerous" ...

  9. replace深入

    var b = 0; var arr = []; str = str.replace(/J/g,function(){ var args = arguments; b++; arr.push(args ...

  10. Create-React-App创建antd-mobile开发环境(学习中的记录)

    (参考别人结合自己的整理得出,若有错误请大神指出) Facebook 官方推出Create-React-App脚手架,基本可以零配置搭建基于webpack的React开发环境,内置了热更新等功能. 详 ...