本文配套視頻地址: 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開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!