您好,登錄后才能下訂單哦!
筆記內(nèi)容:第五個(gè)頁面:更多電影頁面
筆記日期:2018-01-27
因?yàn)橐帉懸粋€(gè)新的頁面,所以第一件事情就是創(chuàng)建好目錄以及文件:
我們需要實(shí)現(xiàn)兩個(gè)功能,一是點(diǎn)擊電影資訊頁面上的 “更多” 時(shí),跳轉(zhuǎn)到更多電影頁面中,二是跳轉(zhuǎn)時(shí)要獲取相應(yīng)的電影類型。
編輯movie-list-template.wxml,修改內(nèi)容如下:
<import src='../movie/movie-template.wxml' />
<template name='movieListTemplate'>
<view class='movie-list-container' style='margin: 0;'>
<view class='inner-container' style='margin: 0;'>
<view class='movie-head'>
<text class='slogan'>{{categoryTitle}}</text>
<!-- 添加點(diǎn)擊事件,并且把電影類型存儲(chǔ)在自定義屬性里 -->
<view catchtap='onMoreTap' class='more' data-category="{{categoryTitle}}">
<text class='more-text'>更多</text>
<image class='more-img' src='/images/icon/arrow-right.png'></image>
</view>
</view>
<view class='movies-container'>
<block wx:for='{{movies}}' wx:for-item='movie'>
<template is='movieTemplate' data='{{...movie}}' />
</block>
</view>
</view>
</view>
</template>
在movie.js文件中增加一個(gè)事件方法,內(nèi)容如下:
// 跳轉(zhuǎn)到更多電影頁面
onMoreTap: function (event) {
// 獲得電影類型
var category = event.currentTarget.dataset.category;
wx.navigateTo({
// 通過參數(shù)把電影類型傳遞過去
url: 'more-movie/more-movie?category=' + category,
});
},
最后是在more-movie.js中測(cè)試一下是否能成功獲取相應(yīng)的電影類型:
Page({
onLoad: function (options) {
// 接收傳遞過來的參數(shù)
var category = options.category;
console.log(category);
},
})
分別點(diǎn)擊不同的電影類型上的 “更多“ ,看看控制臺(tái)的輸出是否對(duì)得上:
以上我們完成了電影類型的獲得,在這之后就需要?jiǎng)討B(tài)的把獲得的數(shù)據(jù)設(shè)置為導(dǎo)航欄標(biāo)題,這樣點(diǎn)擊不同的電影類型時(shí)就能在更多電影頁面的導(dǎo)航欄上顯示不同的標(biāo)題。
官方給出的設(shè)置導(dǎo)航欄文檔地址如下:
https://mp.weixin.qq.com/debug/wxadoc/dev/api/ui.html#wxsettopbartextobject
編輯more-movie.js文件內(nèi)容如下:
Page({
onLoad: function (options) {
// 接收傳遞過來的參數(shù)
var category = options.category;
// 設(shè)置成變量才能在方法之間使用
this.setData({
navigateTitle: category,
});
},
onReady: function (event) {
// 動(dòng)態(tài)設(shè)置導(dǎo)航欄標(biāo)題
wx.setNavigationBarTitle({
title: this.data.navigateTitle,
})
}
})
以上新增的代碼就簡(jiǎn)單的實(shí)現(xiàn)了動(dòng)態(tài)設(shè)置導(dǎo)航欄標(biāo)題。
這一步我們需要實(shí)現(xiàn)在更多電影頁面上,根據(jù)電影類型來向服務(wù)器加載不同電影類型的數(shù)據(jù),由于這個(gè)請(qǐng)求API數(shù)據(jù)的方法挺通用的,所以我把它放到了util.js下,到時(shí)候就可以全局調(diào)用了,提高代碼的復(fù)用性。
編輯util.js代碼如下:
// 請(qǐng)求API的數(shù)據(jù)
function http (url, callBack) {
// 通過reques來發(fā)送請(qǐng)求
wx.request({
url: url,
method: 'GET',
header: {
"Content-Type": "application/json"
},
success: function (res) {
callBack(res.data);
},
fail: function (error) {
console.log("API請(qǐng)求失?。≌?qǐng)檢查網(wǎng)絡(luò)!" + error);
}
});
}
module.exports={
convertToStarsArray: convertToStarsArray,
http: http
}
編輯more-movie.js代碼如下:
var app = getApp();
var util = require('../../../utils/util.js');
Page({
data:{
movies:{}
},
onLoad: function (options) {
// 接收傳遞過來的參數(shù)
var category = options.category;
// 設(shè)置成變量才能在方法之間使用
this.setData({
navigateTitle: category,
});
var dataUrl = "";
switch (category) {
case "正在熱映":
dataUrl = app.globalData.doubanBase + '/v2/movie/in_theaters';
break;
case "即將上映":
dataUrl = app.globalData.doubanBase + '/v2/movie/coming_soon';
break;
case "豆瓣電影Top250":
dataUrl = app.globalData.doubanBase + '/v2/movie/top250';
break;
}
util.http(dataUrl, this.processDoubanData)
},
// 處理API返回的數(shù)據(jù),并綁定到數(shù)據(jù)集里
processDoubanData: function (moviesDouban) {
console.log(moviesDouban)
// 存儲(chǔ)處理完的數(shù)據(jù)
var movies = [];
for (var idx in moviesDouban.subjects) {
var subject = moviesDouban.subjects[idx];
var title = subject.title;
// 處理標(biāo)題過長(zhǎng)
if (title.length >= 6) {
title = title.substring(0, 6) + "...";
}
var temp = {
stars: util.convertToStarsArray(subject.rating.stars),
title: title,
average: subject.rating.average,
coverageUrl: subject.images.large,
movieId: subject.id
};
movies.push(temp);
}
this.setData({
movies: movies
});
},
onReady: function (event) {
// 動(dòng)態(tài)設(shè)置導(dǎo)航欄標(biāo)題
wx.setNavigationBarTitle({
title: this.data.navigateTitle,
})
}
})
以上我們已經(jīng)完成了數(shù)據(jù)的處理,現(xiàn)在只需要完成頁面代碼即可因?yàn)檫@個(gè)更多電影頁面的結(jié)構(gòu)以及樣式都需要進(jìn)行復(fù)用,所以我們還是使用template把這些代碼作為模板代碼。
創(chuàng)建模板文件:
movie-grid-template.wxml文件內(nèi)容:
<import src="../movie/movie-template.wxml" />
<template name="movieGridTemplate">
<view class='grid-container'>
<block wx:for="{{movies}}" wx:for-item="movie">
<view class='single-view-container'>
<template is="movieTemplate" data="{{...movie}}" />
</view>
</block>
</view>
</template>
movie-grid-template.wxss文件內(nèi)容:
@import "../movie/movie-template.wxss";
.single-view-container{
float: left;
margin-bottom: 40rpx;
}
.grid-container{
margin: 40rpx 0 40rpx 6rpx;
}
more-movie.wxml就只需要引用模板即可,代碼的可復(fù)用性越高,需要寫的代碼就越少:
<import src="../movie-grid/movie-grid-template.wxml" />
<template is="movieGridTemplate" data="{{movies}}" />
more-movie.wxss也是只需要引用模板即可:
@import "../movie-grid/movie-grid-template.wxss";
運(yùn)行效果:
以上我們實(shí)現(xiàn)了更多電影頁面,但是每次只能加載20條電影數(shù)據(jù),我們希望能夠有一個(gè)上滑加載更多數(shù)據(jù)的功能,所以本節(jié)就是演示如何實(shí)現(xiàn)這樣一個(gè)功能。
實(shí)現(xiàn)這樣一個(gè)功能我們需要使用到scroll-view組件,該組件的官方說明文檔地址如下:
https://mp.weixin.qq.com/debug/wxadoc/dev/component/scroll-view.html
編輯movie-grid-template.wxml文件內(nèi)容,將view換成scroll-view:
<import src="../movie/movie-template.wxml" />
<template name="movieGridTemplate">
<scroll-view scroll-y="true" scroll-x="false" bindscrolltolower="onScrollLower" class='grid-container'>
<block wx:for="{{movies}}" wx:for-item="movie">
<view class='single-view-container'>
<template is="movieTemplate" data="{{...movie}}" />
</view>
</block>
</scroll-view>
</template>
編輯movie-grid-template.wxss文件內(nèi)容,給grid-container設(shè)置一個(gè)固定的高度,因?yàn)樾枰幸粋€(gè)固定的高度才知道是否已經(jīng)滾動(dòng)到底部了:
@import "../movie/movie-template.wxss";
.single-view-container{
float: left;
margin-bottom: 40rpx;
}
.grid-container{
/*必須要給一個(gè)固定的高度*/
height: 1300rpx;
margin: 40rpx 0 40rpx 6rpx;
}
最后是編輯more-movie.js文件,這一步我們需要完成三件事情:
1.實(shí)現(xiàn)事件方法,當(dāng)觸發(fā)bindscrolltolower時(shí)向API請(qǐng)求更多的數(shù)據(jù)
2.我們都知道第一次請(qǐng)求API時(shí)默認(rèn)是請(qǐng)求0-19條數(shù)據(jù),所以我們需要有一個(gè)變量充當(dāng)計(jì)數(shù)器,讓這個(gè)變量的值在每一次請(qǐng)求成功后都進(jìn)行累加,這樣才能讓start參數(shù)的值進(jìn)行一個(gè)遞增,例如第一次是0-19,第二次就得是20-39,第三次就是40-59......以此類推
3.能夠?qū)崿F(xiàn)不斷的往后加載數(shù)據(jù)之后,我們需要將這些數(shù)據(jù)都整合起來,不然的話數(shù)據(jù)會(huì)進(jìn)行覆蓋,那么每一次加載都只能顯示20條數(shù)據(jù),這顯然不是我們想要的效果。我們想要的是數(shù)據(jù)進(jìn)行疊加,第一次顯示20條數(shù)據(jù),第二次顯示40條數(shù)據(jù),第三次顯示60條數(shù)據(jù)......以此類推
理清思路后,編輯more-movie.js文件內(nèi)容如下:
var app = getApp();
var util = require('../../../utils/util.js');
Page({
data: {
movies: {},
totalCount: 0,
isEmpty:true, // 用于判斷movies是否為空,是的話就是第一次請(qǐng)求數(shù)據(jù)
},
onLoad: function (options) {
// 接收傳遞過來的參數(shù)
var category = options.category;
// 設(shè)置成變量才能在方法之間使用
this.setData({
navigateTitle: category,
});
var dataUrl = "";
switch (category) {
case "正在熱映":
dataUrl = app.globalData.doubanBase + '/v2/movie/in_theaters';
break;
case "即將上映":
dataUrl = app.globalData.doubanBase + '/v2/movie/coming_soon';
break;
case "豆瓣電影Top250":
dataUrl = app.globalData.doubanBase + '/v2/movie/top250';
break;
}
this.setData({
requestUrl: dataUrl
});
util.http(dataUrl, this.processDoubanData)
},
// 觸發(fā)bindscrolltolower事件時(shí)加載更多數(shù)據(jù)
onScrollLower: function (event) {
var nextUrl = this.data.requestUrl + "?start=" + this.data.totalCount + "&count=20";
util.http(nextUrl, this.processDoubanData)
},
// 處理API返回的數(shù)據(jù),并綁定到數(shù)據(jù)集里
processDoubanData: function (moviesDouban) {
console.log(moviesDouban)
// 存儲(chǔ)處理完的數(shù)據(jù)
var movies = [];
for (var idx in moviesDouban.subjects) {
var subject = moviesDouban.subjects[idx];
var title = subject.title;
// 處理標(biāo)題過長(zhǎng)
if (title.length >= 6) {
title = title.substring(0, 6) + "...";
}
var temp = {
stars: util.convertToStarsArray(subject.rating.stars),
title: title,
average: subject.rating.average,
coverageUrl: subject.images.large,
movieId: subject.id
};
movies.push(temp);
}
// 將新舊數(shù)據(jù)進(jìn)行整合在一起
var totalMovies={};
if(!this.data.isEmpty){
// 不為空代表不是第一次請(qǐng)求才進(jìn)行整合
totalMovies=this.data.movies.concat(movies);
}else{
// 第一次請(qǐng)求則需要不需要整合,并且需要改變isEmpty的狀態(tài)
totalMovies = movies;
this.data.isEmpty=false;
}
this.setData({
movies: totalMovies
});
// 計(jì)數(shù)器,數(shù)據(jù)綁定成功后才進(jìn)行累加
this.data.totalCount += 20;
},
onReady: function (event) {
// 動(dòng)態(tài)設(shè)置導(dǎo)航欄標(biāo)題
wx.setNavigationBarTitle({
title: this.data.navigateTitle,
})
}
})
以上我們完成了更多數(shù)據(jù)的加載,但是只是這樣的話,體驗(yàn)還不夠良好,我們需要在數(shù)據(jù)加載時(shí)提示用戶一個(gè)loading狀態(tài),這樣體驗(yàn)起來就沒那么生硬。
有幾個(gè)API都可以實(shí)現(xiàn)這個(gè)loading的效果,我這里使用的是wx.showNavigationBarLoading(),以下是關(guān)于交互反饋API的官方文檔地址:
https://mp.weixin.qq.com/debug/wxadoc/dev/api/ui.html#wxshownavigationbarloading
編輯more-movie.js文件中的onScrollLower以及processDoubanData方法,在方法代碼的末尾加上以下內(nèi)容:
onScrollLower: function (event) {
// 其他代碼忽略
// 設(shè)置loading狀態(tài)
wx.showNavigationBarLoading();
},
processDoubanData: function (moviesDouban) {
// 其他代碼忽略
// 結(jié)束loading狀態(tài)
wx.hideNavigationBarLoading();
},
通過這兩個(gè)API就簡(jiǎn)單的實(shí)現(xiàn)了數(shù)據(jù)加載時(shí)提示loading狀態(tài)。
幾乎所有的app里都有下拉頁面重新刷新數(shù)據(jù)的功能,所以我們也希望有一個(gè)這樣的功能。不過目前有一個(gè)小問題,我們是使用scroll-view組件來實(shí)現(xiàn)下滑加載更多數(shù)據(jù)的,但是130400版本更新后卻導(dǎo)致下拉刷新和scroll-view不能同時(shí)使用。
導(dǎo)致onPullDownRefresh事件函數(shù)無法執(zhí)行的原因是頁面里包含一個(gè)scroll-view組件。而scroll-view組件和onPullDownRefresh在130400版本里是沖突的。當(dāng)我們?cè)陧撁胬锘瑒?dòng)scroll-view時(shí),只是滑動(dòng)這個(gè)組件,不再可以觸發(fā)onPullDownRefresh。當(dāng)然,你還是可以在scroll-view區(qū)域外滑動(dòng)頁面執(zhí)行onPullDownRefresh。什么意思呢?看下面的圖:
點(diǎn)擊箭頭那塊兒的空白部分依然可以執(zhí)行onPullDownRefresh,但除此之外任何位置都不可以執(zhí)行刷新事件。原因是因?yàn)椋^的空白部分不屬于scroll-view這個(gè)組件的區(qū)域,它是屬于page頁面的區(qū)域,page頁面依然可以執(zhí)行onPullDownRefresh。但如果是在scroll-view組件內(nèi)部去拉動(dòng)頁面,則滑動(dòng)的動(dòng)作只對(duì)scroll-view組件有效,不再對(duì)page頁面有效,自然就不會(huì)再觸發(fā)頁面的onPullDownRefresh。
解決方案如下(下拉刷新和加載更多同時(shí)存在的方法):
放棄使用scroll-view組件,改用view組件。那么既然放棄了scroll-view組件,上滑加載更多就不能再使用scroll-view的bindscrolltolower="onScrollLower"事件。
那么view組件如何監(jiān)控上滑到底的事件?MINA在Page里還提供了一個(gè)onReachBottom事件,使用這個(gè)事件來監(jiān)聽頁面上滑到底。
具體改動(dòng):
more-movie.js文件:
// 觸發(fā)onReachBottom事件時(shí)加載更多的數(shù)據(jù)
onReachBottom: function (event) {
var nextUrl = this.data.requestUrl + "?start=" + this.data.totalCount + "&count=20";
util.http(nextUrl, this.processDoubanData);
// 設(shè)置loading狀態(tài)
wx.showNavigationBarLoading();
},
將原本的onScrollLower方法更名成onReachBottom,方法的內(nèi)容無需任何改動(dòng)。
movie-grid-template.wxml文件:
<import src="../movie/movie-template.wxml" />
<template name="movieGridTemplate">
<view class='grid-container'>
<block wx:for="{{movies}}" wx:for-item="movie">
<view class='single-view-container'>
<template is="movieTemplate" data="{{...movie}}" />
</view>
</block>
</view>
</template>
完成以上的修改后,才能開始著手開始實(shí)現(xiàn)我們的下拉頁面重新刷新數(shù)據(jù)的功能,首先我們需要編輯more-movie.json文件,增加如下內(nèi)容,以開啟下拉刷新功能:
{
"enablePullDownRefresh": "true"
}
該配置語句的官網(wǎng)說明文檔地址:
https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html
當(dāng)下拉頁面下拉刷新時(shí)會(huì)觸發(fā)onPullDownRefresh事件方法,所以最后就是編輯more-movie.js文件,實(shí)現(xiàn)onPullDownRefresh方法,以及在processDoubanData方法里需要添加一句代碼:
// 當(dāng)下拉刷新時(shí)會(huì)觸發(fā)onPullDownRefresh方法,所以我們要實(shí)現(xiàn)它
onPullDownRefresh: function (event) {
var refreshUrl = this.data.requestUrl + "?start=0&count=20";
util.http(refreshUrl, this.processDoubanData);
// 清空movies里的數(shù)據(jù)
this.data.movies = {};
// 將totalCount歸零
this.data.totalCount = 0;
// 并且改變isEmpty狀態(tài)
this.data.isEmpty = true;
// 設(shè)置loading狀態(tài)
wx.showNavigationBarLoading();
},
processDoubanData: function (moviesDouban) {
// 其他代碼忽略
// 停止刷新數(shù)據(jù)
wx.stopPullDownRefresh();
},
很多人以為 backgroundColor 設(shè)置的是頁面的背景顏色,而且官方文檔上寫的也不是很清楚,就寫了個(gè) “窗口的背景色” 。經(jīng)過試驗(yàn)發(fā)現(xiàn)實(shí)際上 backgroundColor 設(shè)置的是我們下拉頁面時(shí)的那個(gè)背景顏色,我們可以做一個(gè)簡(jiǎn)單的小實(shí)驗(yàn),在more-movie.json文件中增加一行配置:
{
"enablePullDownRefresh": "true",
"backgroundColor":"red"
}
然后到more-movie頁面中,然后下拉頁面,可以看到背景顏色是我們?cè)O(shè)置的red紅色:
或許不能說是下拉頁面時(shí)的背景顏色,嚴(yán)格來說是Page頁面底層下的背景顏色,也就是脫離了Page頁面時(shí)裸露出來的頁面背景。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。