本文配套视频地址: v.qq.com/x/page/z055…javascript
开始前请把
ch3-2
分支中的code/
目录导入微信开发工具html
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
函数中用来初始化页面组件
java
而后要作的就是获取列表的数据,初始化数据的工做咱们通常放在生命周期的 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
展现,因此咱们须要作一层数据转换,把接口数据转换成视图数据。微信小程序
先看下后端返回的数据结构数组
咱们须要作两件事情微信
data
数组,对返回的日期格式化,当天的显示 今天
,若是是今年的文章,显示月日格式 08-21
;若是是往年的文章,显示标准的年月日格式 2015-06-12
。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官网:www.ikcamp.com
访问官网更快阅读所有免费分享课程:《iKcamp出品|全网最新|微信小程序|基于最新版1.0开发者工具之初中级培训教程分享》。 包含:文章、视频、源代码
iKcamp原创新书《移动Web前端高效开发实战》已在亚马逊、京东、当当开售。
与
“每天练口语”
小程序总榜排名第4、教育类排名第一的研发团队,面对面沟通交流。
2019年,iKcamp原创新书《Koa与Node.js开发实战》已在京东、天猫、亚马逊、当当开售啦!