WeChat small program teaching chapter 3 (with video): small program intermediate practical tutorial: list - page logic processing
The video accompanying this article is at. https://v.qq.com/x/page/n0554dndrez.html
Before you start, please put ch3-2 in the branch code/ Catalog Import WeChat Development Tools
'use strict'; import util from '../../utils/index'; import config from '../../utils/config'; let app = getApp(); let isDEV = config.isDev; // Subsequent code will be placed in this object let handler = { } Page(handler)
We start by digging out the data relevant to the rendering and adding it to the handler target group data in the field (Model layer) modify index.js hit the target handler Object.
// Some code is omitted here let handler = { data: { page: 1, //the current page of data loaded days: 3, pageSize: 4, totalSize: 0, hasMore: true,// Used to determine the drop-down load more action articleList: [], // Holds the article list data, associated with the view defaultImg: config.defaultImg }, }
Caution. Subsequent code additions are placed in the handler object, it will be passed to the Page function is used to initialize the page components in the
Then all you have to do is get the data for the list, and the initialization of the data is something we generally put in the lifecycle onLoad() RI.
let handler = { onLoad (options) { this.requestArticle() }, /* * Get article list data */ requestArticle () { util.request({ url: 'list', mock: true, data: { tag:' WeChat Hot', start: this.data.page || 1, days: this.data.days || 3, pageSize: this.data.pageSize, langs: config.appLang || 'en' } }) .then(res => { console.log( res ) }); } }
modify requestArticle Function.
let handler = { // Some code is omitted here requestArticle () { util.request({ url: 'list', mock: true, data: { tag:' WeChat Hot', start: this.data.page || 1, days: this.data.days || 3, pageSize: this.data.pageSize, langs: config.appLang || 'en' } }) .then(res => { // Data returned normally if (res && res.status === 0 && res.data && res.data.length) { // Normal data do something console.log(res) } /* * If there is no data on the first page loaded, there is an anomaly in the data * Handling: pop-up exception message (default message) and set the drop-down loading function to be unavailable */ else if (this.data.page === 1 && res.data && res.data.length === 0) { util.alert(); this.setData({ hasMore: false }); } /* * If there's no data on the non-first page, that means there's no data left, just disable the drop-down loading feature */ else if (this.data.page !== 1 && res.data && res.data.length === 0) { this.setData({ hasMore: false }); } /* * Return Exception Error * Display the error message returned by the backend and set the drop-down load function to be unavailable */ else { util.alert('prompt', res); this.setData({ hasMore: false }); return null; } }) } }
Above we put wx.request Repackaged as Promise form, we are actually requesting the mock data. But the data requested by the interface will in the vast majority of cases not be directly applicable to the UI display, so we need to do a layer of data transformation to convert the interface data into view data.
Let's first look at the data structure returned by the backend
We need to do two things.
modify app.js , add global variables visitedArticles
globalData: { user: { name: '', avator: '' }, visitedArticles: '' }
modify index.js hit the target requestArticle Function.
let handler = { // Some code is omitted here requestArticle () { // Note: Change the code here if (res && res.status === 0 && res.data && res.data.length) { let articleData = res.data; // Formatting raw data let formatData = this.formatArticleData(articleData); console.log( formatData ) } } }
Add code to format the data for the list.
let handler = { // Some code is omitted here /* * Formatting article list data */ formatArticleData (data) { let formatData = undefined; if (data && data.length) { formatData = data.map((group) => { // Formatting date group.formateDate = this.dateConvert(group.date); if (group && group.articles) { let formatArticleItems = group.articles.map((item) => { // Determine if it has been visited item.hasVisited = this.isVisited(item.contentId); return item; }) || []; group.articles = formatArticleItems; } return group }) } return formatData; }, /* * Formatting the original date string '2017-06-12' * return ' today' / 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 = ' today'; } else if (originYear < todayYear) { let splitStr = dateStr.split('-'); convertStr = `${splitStr[0]} year${splitStr[1]} month${splitStr[2]} sun`; } else { convertStr = dateStr.slice(5).replace('-', ' month') + ' sun' } return convertStr; }, /* * Determine if the article has been visited * @param contentId */ isVisited (contentId) { let visitedArticles = app.globalData && app.globalData.visitedArticles || ''; return visitedArticles.indexOf(`${contentId}`) > -1; }, }
Normally, the data printed from the console at this point is now formatted as standard, and in the next step, we need to add it to the data hit the target articleList field inside, so that the view has the data to render
modify index.js Increase renderArticle function. Since each request is for a particular page of data, in the function, we need to take the list data that comes over each request concat (splicing) to articleList Medium.
let handler = { // Some code is omitted here renderArticle (data) { if (data && data.length) { let newList = this.data.articleList.concat(data); this.setData({ articleList: newList }) } } }
(located) at requestArticle The function calls renderArticle:
let handler = { // Some code is omitted here requestArticle () { // Note: Change the code here if (res && res.status === 0 && res.data && res.data.length) { let articleData = res.data; // Formatting raw data let formatData = this.formatArticleData(articleData); this.renderArticle( formatData ) } } }
final index.js The document is this.
'use strict'; import util from '../../utils/index' import config from '../../utils/config' let app = getApp() let isDEV = config.isDev // Subsequent code will be placed in this object let handler = { data: { page: 1, //the current page number days: 3, pageSize: 4, totalSize: 0, hasMore: true,// Used to determine the drop-down load more action articleList: [], // Holds the article list data defaultImg: config.defaultImg }, onLoad(options) { this.requestArticle(); }, /* * Get article list data */ requestArticle() { util.request({ url: 'list', mock: true, data: { tag: ' WeChat Hot', start: this.data.page || 1, days: this.data.days || 3, pageSize: this.data.pageSize, langs: config.appLang || 'en' } }) .then(res => { // Data returned normally if (res && res.status === 0 && res.data && res.data.length) { let articleData = res.data; // Formatting raw data let formatData = this.formatArticleData(articleData); this.renderArticle(formatData) } /* * If there is no data on the first page loaded, there is an anomaly in the data * Handling: pop-up exception message (default message) and set the drop-down loading function to be unavailable */ else if (this.data.page === 1 && res.data && res.data.length === 0) { util.alert(); this.setData({ hasMore: false }); } /* * If there's no data on the non-first page, that means there's no data left, just disable the drop-down loading feature */ else if (this.data.page !== 1 && res.data && res.data.length === 0) { this.setData({ hasMore: false }); } /* * Return Exception Error * Display the error message returned by the backend and set the drop-down load function to be unavailable */ else { util.alert('prompt', res); this.setData({ hasMore: false }); return null; } }) }, /* * Formatting article list data */ formatArticleData(data) { let formatData = undefined; if (data && data.length) { formatData = data.map((group) => { // Formatting date group.formateDate = this.dateConvert(group.date); if (group && group.articles) { let formatArticleItems = group.articles.map((item) => { // Determine if it has been visited item.hasVisited = this.isVisited(item.contentId); return item; }) || []; group.articles = formatArticleItems; } return group }) } return formatData; }, /* * Formatting the original date string '2017-06-12' * return ' today' / 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 = ' today'; } else if (originYear < todayYear) { let splitStr = dateStr.split('-'); convertStr = `${splitStr[0]} year${splitStr[1]} month${splitStr[2]} sun`; } else { convertStr = dateStr.slice(5).replace('-', ' month') + ' sun' } return convertStr; }, /* * Determine if the article has been visited * @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)
In the next post, we will combine the data with the view layer to present the view layer dynamically.