最后一个页面:构建电影详情页面
笔记内容:最后一个页面:构建电影详情页面
笔记日期:2018-02-02
电影搜索页面构建
我们想要有一个搜索电影的功能,需要在电影资讯页面顶部编写一个搜索框,当我们的鼠标焦点位于该搜索框时,就会显示出电影搜索页面,而点击搜索框的关闭图标时,需要隐藏电影搜索页面。所以这个电影搜索页面不是一个单独的页面文件,而是用隐/显的方式来做。
搜索框效果图:
要实现这个搜索框,我们首先需要一个表单组件:input,该组件的官方说明文档地址如下:
https://mp.weixin.qq.com/debug/wxadoc/dev/component/input.html
然后还需要用到icon组件,该组件的官方说明文档地址如下:
https://mp.weixin.qq.com/debug/wxadoc/dev/component/icon.html
1.编辑movies.wxml代码如下:
2.编辑movies.wxss代码如下:
@import "movie-list/movie-list-template.wxss";@import "movie-grid/movie-grid-template.wxss";.container{ background-color: #f2f2f2;}.container view{ margin-bottom: 30rpx;}.search{ background-color: #f2f2f2; height: 80rpx; width: 100%; display: flex; flex-direction: row;}.search-img{ margin: auto 0 auto 20rpx;}.search input{ height: 100%; width: 600rpx; margin-left: 20px; font-size: 28rpx;}.placeholder{ font-size: 14px; color: #d1d1d1; margin-left: 20rpx;}.search-panel{ position: absolute; top: 80rpx;}.xx-img{ height: 30rpx; width: 30rpx; margin: auto 0 auto 10rpx;}
3.编辑movies.js代码如下:
var app = getApp();var util = require('../../utils/util.js');Page({ data: { // 需要有一个初始值 inTheaters: {}, comingSoon: {}, top250: {}, searchResult: {}, containerShow: true, searchPanelShow: false, }, onLoad: function (event) { var inTheatersUrl = app.globalData.doubanBase + '/v2/movie/in_theaters?start=0&count=3'; var comingSoonUrl = app.globalData.doubanBase + '/v2/movie/coming_soon?start=0&count=3'; var top250Url = app.globalData.doubanBase + '/v2/movie/top250?start=0&count=3'; this.getMovieListData(inTheatersUrl, "inTheaters", "正在热映"); this.getMovieListData(comingSoonUrl, "comingSoon", "即将上映"); this.getMovieListData(top250Url, "top250", "豆瓣电影Top250"); }, // 跳转到更多电影页面 onMoreTap: function (event) { // 获得电影类型 var category = event.currentTarget.dataset.category; wx.navigateTo({ // 通过参数把电影类型传递过去 url: 'more-movie/more-movie?category=' + category, }); }, // 请求API的数据 getMovieListData: function (url, settedkey, categoryTitle) { var that = this; // 通过reques来发送请求 wx.request({ url: url, method: 'GET', header: { "Content-Type": "application/json" }, success: function (res) { that.processDoubanData(res.data, settedkey, categoryTitle); }, fail: function () { console.log("API请求失败!请检查网络!"); } }); }, // 关闭电影搜索页面 onCancelImgTap: function (event) { this.setData({ containerShow: true, searchPanelShow: false, searchResult: {}, cleanValue: '', }); }, // 显示电影搜索页面 onBindFocus: function (event) { this.setData({ containerShow: false, searchPanelShow: true, }); }, // 搜索电影数据 onBindFirm: function (event) { var text = event.detail.value; var searchUrl = app.globalData.doubanBase + "/v2/movie/search?q=" + text; this.getMovieListData(searchUrl, "searchResult", ""); }, // 处理API返回的数据 processDoubanData: function (moviesDouban, settedkey, categoryTitle) { // 存储处理完的数据 var movies = []; for (var idx in moviesDouban.subjects) { var subject = moviesDouban.subjects[idx]; var title = subject.title; // 处理标题过长 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); } if (categoryTitle == '正在热映') { this.setData({ placeholder: movies[0]['title'] }); } // 动态赋值 var readyData = {}; readyData[settedkey] = { categoryTitle: categoryTitle, movies: movies }; this.setData(readyData); },})
运行效果:
编写电影详情页面
以上我们已经完成了大部分的页面了,现在我们来完成最后一个影详情页面,我们希望在电影资讯页面上点击某一部电影时,要能跳转到该电影的详情页面,所以这是一个新的页面,我们首先要做的事情就是创建这个页面的目录及文件:
然后首先是在movie-template.wxml文件中加上一个点击事件:
{{title}}
接着在movies.js文件中编写一段跳转页面的逻辑代码:
// 跳转到电影详情页面 onMovieTap:function(event){ // 获得电影的id var movieId = event.currentTarget.dataset.movieid; wx.navigateTo({ // 通过参数把电影的subject id传递过去 url: 'movie-detail/movie-detail?id=' + movieId, }); },
然后在movie-detail.js里接收id参数,向API请求数据,把服务器返回的数据在控制台中打印出来:
var app = getApp();var util = require('../../../utils/util.js');Page({ data: { }, onLoad: function (options) { var movieId = options.id; var url = app.globalData.doubanBase + "/v2/movie/subject/" + movieId; util.http(url, this.processDoubanData); }, processDoubanData:function(data){ console.log(data) },})
确定能正常获取到数据后,就可以开始处理数据了,主要的逻辑是做数据的筛选及判空容错,编写movie-detail.js代码如下:
var app = getApp();var util = require('../../../utils/util.js');Page({ data: { movie: {}, }, onLoad: function (options) { var movieId = options.id; var url = app.globalData.doubanBase + "/v2/movie/subject/" + movieId; util.http(url, this.processDoubanData); }, // 处理API返回的数据 processDoubanData: function (data) { // 初始一些数据的默认值 var director = { avatar: "", name: "", id: "" } // 处理可能会出现的空值 if (data.directors[0] != null) { if (data.directors[0].avatars != null) { director.avatar = data.directors[0].avatars.large; } director.name = data.directors[0].name; director.id = data.directors[0].id; } // 填充数据 var movie = { movieImg: data.images ? data.images.large : "", // 处理可能会出现的空值 country: data.countries[0], title: data.title, originalTitle: data.original_title, wishCount: data.wish_count, commentCount: data.comments_count, year: data.year, generes: data.genres.join("、"), // 把数组转化成用 、分割的字符串 stars: util.convertToStarsArray(data.rating.stars), score: data.rating.average, director: director, casts: util.convertToCastString(data.casts), castsInfo: util.convertToCastInfos(data.casts), summary: data.summary, } console.log(movie) // 绑定数据 this.setData({ movie: movie }); },})
接着util.js代码如下:
// 以上代码略// 把演员的名字用斜杠分割function convertToCastString(casts) { var castsjoin = ""; for (var idx in casts) { castsjoin = castsjoin + casts[idx].name + "/"; } return castsjoin.substring(0, castsjoin.length - 2);}// 处理演员的名称与照片function convertToCastInfos(casts) { var castsArray = [] for (var idx in casts) { var cast = { img: casts[idx].avatars ? casts[idx].avatars.large : "", // 处理可能会出现的空值 name: casts[idx].name } castsArray.push(cast); } return castsArray;}module.exports = { convertToStarsArray: convertToStarsArray, http: http, convertToCastString: convertToCastString, convertToCastInfos: convertToCastInfos}
然后编译运行看看控制台里是否有正常打印出数据。
以上我们完成了数据获取以及处理,现在我们就可以开始编写页面上的代码了。首先编写电影详情页面的骨架代码,这个页面的代码还挺多的,不过并不复杂:
movie-detail.wxml骨架代码:
{{movie.title}} {{movie.country + " . " + movie.year}} {{movie.wishCount}} 人喜欢 {{movie.commentCount}} 条评论 {{movie.originalTitle}} 评分 导演 {{movie.director.name}} 影人 {{movie.casts}} 类型 {{movie.generes}} 剧情简介 {{movie.summary}} 影人 {{item.name}}
movie-detail.wxss样式代码:
@import "../stars/stars-template.wxss";.container { display: flex; flex-direction: column;}.head-img { width: 100%; height: 320rpx; /* 图片模糊效果 */ -webkit-filter: blur(20px);}.head-img-hover { width: 100%; height: 320rpx; position: absolute; top: 0; left: 0; display: flex; flex-direction: column;}.main-title { font-size: 19px; color: #fff; font-weight: bold; margin-top: 50rpx; margin-left: 40rpx; letter-spacing: 2px;}.sub-title { font-size: 28rpx; color: #fff; margin-left: 40rpx; margin-top: 30rpx;}.like { display: flex; flex-direction: row; margin-top: 30rpx; margin-left: 40rpx;}.highlight-font { color: #f21146; font-size: 22rpx; margin-right: 10rpx;}.plain-font { color: #666; font-size: 22rpx; margin-right: 30rpx;}.movie-img { height: 238rpx; width: 175rpx; position: absolute; top: 160rpx; right: 30rpx;}.summary { margin-left: 40rpx; margin-top: 40rpx; color: #777;}.original-title { color: #1f3463; font-size: 24rpx; font-weight: bold; margin-bottom: 40rpx;}.flex-row { display: flex; flex-direction: row; margin-bottom: 10rpx;}.mark { margin-right: 30rpx; white-space: nowrap; color: #999;}.hr { margin-top: 45rpx; height: 1px; width: 100%; background-color: #d9d9d9;}.synopsis { margin-left: 40rpx; display: flex; flex-direction: column; margin-top: 50rpx;}.synopsis-font { color: #999;}.summary-content { margin-top: 20rpx; margin-right: 40rpx; line-height: 40rpx; letter-spacing: 1px;}.cast { margin-left: 40rpx; display: flex; flex-direction: column; margin-top: 50rpx;}.cast-font { color: #999; margin-bottom: 40rpx;}.cast-container { display: inline-flex; flex-direction: column; margin-bottom: 50rpx; margin-right: 40rpx; width: 170rpx; text-align: center; /* 正常换行 */ white-space: normal;}.cast-imgs { /* 禁止自动换行 */ white-space: nowrap;}.cast-img { width: 170rpx; height: 210rpx;}.cast-name { margin: 10rpx auto 0;}
movie-detail.js里增加以下代码:
// 查看图片 viewMoviePostImg: function (event) { var src = event.currentTarget.dataset.src; wx.previewImage({ current: src, // 当前显示图片的http链接 urls: [src], // 需要预览的图片的http链接 }) },
其中用到的image组件的官方说明文档地址如下:
https://mp.weixin.qq.com/debug/wxadoc/dev/component/image.html
然后我们希望更多电影页面中也能够跳转到电影详情页,所以需要在more-movie.js文件中增加以下代码:
// 跳转到电影详情页面 onMovieTap: function (event) { // 获得电影的id var movieId = event.currentTarget.dataset.movieid; wx.navigateTo({ // 通过参数把电影的subject id传递过去 url: '../movie-detail/movie-detail?id=' + movieId, }); },
所有的代码编写完成后,运行效果如下:
到目前为止,整个小程序的开发就告一段落了,这个笔记的目的也只是为了记录一下开发的过程,所以其中对细节没有过多的介绍,不过基本上代码也都注释了,也是为了方便以后遇到类似的功能可以参考实现思路,毕竟像我这种代码写完就忘的人。