第五个页面:更多电影页面

笔记内容:第五个页面:更多电影页面
笔记日期:2018-01-27


跳转到更多电影页面以及获取电影类型

因为要编写一个新的页面,所以第一件事情就是创建好目录以及文件:

我们需要实现两个功能,一是点击电影资讯页面上的 “更多” 时,跳转到更多电影页面中,二是跳转时要获取相应的电影类型。

编辑movie-list-template.wxml,修改内容如下:

<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>
        <!-- 添加点击事件,并且把电影类型存储在自定义属性里 -->
        <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文件中增加一个事件方法,内容如下:

  // 跳转到更多电影页面
  onMoreTap: function (event) {
    // 获得电影类型
    var category = event.currentTarget.dataset.category;
    wx.navigateTo({
      // 通过参数把电影类型传递过去
      url: ‘more-movie/more-movie?category=‘ + category,
    });
  },

最后是在more-movie.js中测试一下是否能成功获取相应的电影类型:

Page({

  onLoad: function (options) {
    // 接收传递过来的参数
    var category = options.category;
    console.log(category);
  },

})

分别点击不同的电影类型上的 “更多“ ,看看控制台的输出是否对得上:


动态设置导航栏标题

以上我们完成了电影类型的获得,在这之后就需要动态的把获得的数据设置为导航栏标题,这样点击不同的电影类型时就能在更多电影页面的导航栏上显示不同的标题。

官方给出的设置导航栏文档地址如下:

https://mp.weixin.qq.com/debug/wxadoc/dev/api/ui.html#wxsettopbartextobject

编辑more-movie.js文件内容如下:

Page({

  onLoad: function (options) {
    // 接收传递过来的参数
    var category = options.category;

    // 设置成变量才能在方法之间使用
    this.setData({
      navigateTitle: category,
    });
  },

  onReady: function (event) {
    // 动态设置导航栏标题
    wx.setNavigationBarTitle({
      title: this.data.navigateTitle,
    })
  }

})

以上新增的代码就简单的实现了动态设置导航栏标题。


在更多电影页面上加载数据

这一步我们需要实现在更多电影页面上,根据电影类型来向服务器加载不同电影类型的数据,由于这个请求API数据的方法挺通用的,所以我把它放到了util.js下,到时候就可以全局调用了,提高代码的复用性。

编辑util.js代码如下:

// 请求API的数据
function http (url, callBack) {

  // 通过reques来发送请求
  wx.request({
    url: url,
    method: ‘GET‘,
    header: {
      "Content-Type": "application/json"
    },
    success: function (res) {
      callBack(res.data);
    },
    fail: function (error) {
      console.log("API请求失败!请检查网络!" + 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) {
    // 接收传递过来的参数
    var category = options.category;

    // 设置成变量才能在方法之间使用
    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返回的数据,并绑定到数据集里
  processDoubanData: function (moviesDouban) {
    console.log(moviesDouban)
    // 存储处理完的数据
    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);
    }

    this.setData({
      movies: movies
    });
  },

  onReady: function (event) {
    // 动态设置导航栏标题
    wx.setNavigationBarTitle({
      title: this.data.navigateTitle,
    })
  }

})

实现movie-grid template

以上我们已经完成了数据的处理,现在只需要完成页面代码即可因为这个更多电影页面的结构以及样式都需要进行复用,所以我们还是使用template把这些代码作为模板代码。

创建模板文件:

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>

movie-grid-template.wxss文件内容:

@import "../movie/movie-template.wxss";

.single-view-container{
  float: left;
  margin-bottom: 40rpx;
}

.grid-container{
  margin: 40rpx 0 40rpx 6rpx;
}

more-movie.wxml就只需要引用模板即可,代码的可复用性越高,需要写的代码就越少:

<import src="../movie-grid/movie-grid-template.wxml" />
<template is="movieGridTemplate" data="{{movies}}" />

more-movie.wxss也是只需要引用模板即可:

@import "../movie-grid/movie-grid-template.wxss";

运行效果:


实现上滑加载更多数据

以上我们实现了更多电影页面,但是每次只能加载20条电影数据,我们希望能够有一个上滑加载更多数据的功能,所以本节就是演示如何实现这样一个功能。

实现这样一个功能我们需要使用到scroll-view组件,该组件的官方说明文档地址如下:

https://mp.weixin.qq.com/debug/wxadoc/dev/component/scroll-view.html

编辑movie-grid-template.wxml文件内容,将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文件内容,给grid-container设置一个固定的高度,因为需要有一个固定的高度才知道是否已经滚动到底部了:

@import "../movie/movie-template.wxss";

.single-view-container{
  float: left;
  margin-bottom: 40rpx;
}

.grid-container{
  /*必须要给一个固定的高度*/
  height: 1300rpx;
  margin: 40rpx 0 40rpx 6rpx;
}

最后是编辑more-movie.js文件,这一步我们需要完成三件事情:

1.实现事件方法,当触发bindscrolltolower时向API请求更多的数据

2.我们都知道第一次请求API时默认是请求0-19条数据,所以我们需要有一个变量充当计数器,让这个变量的值在每一次请求成功后都进行累加,这样才能让start参数的值进行一个递增,例如第一次是0-19,第二次就得是20-39,第三次就是40-59......以此类推

3.能够实现不断的往后加载数据之后,我们需要将这些数据都整合起来,不然的话数据会进行覆盖,那么每一次加载都只能显示20条数据,这显然不是我们想要的效果。我们想要的是数据进行叠加,第一次显示20条数据,第二次显示40条数据,第三次显示60条数据......以此类推

理清思路后,编辑more-movie.js文件内容如下:

var app = getApp();
var util = require(‘../../../utils/util.js‘);

Page({
  data: {
    movies: {},
    totalCount: 0,
    isEmpty:true,  // 用于判断movies是否为空,是的话就是第一次请求数据
  },
  onLoad: function (options) {
    // 接收传递过来的参数
    var category = options.category;

    // 设置成变量才能在方法之间使用
    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)
  },

  // 触发bindscrolltolower事件时加载更多数据
  onScrollLower: function (event) {
    var nextUrl = this.data.requestUrl + "?start=" + this.data.totalCount + "&count=20";
    util.http(nextUrl, this.processDoubanData)
  },

  // 处理API返回的数据,并绑定到数据集里
  processDoubanData: function (moviesDouban) {
    console.log(moviesDouban)
    // 存储处理完的数据
    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);
    }
    // 将新旧数据进行整合在一起
    var totalMovies={};
    if(!this.data.isEmpty){
      // 不为空代表不是第一次请求才进行整合
      totalMovies=this.data.movies.concat(movies);
    }else{
      // 第一次请求则需要不需要整合,并且需要改变isEmpty的状态
      totalMovies = movies;
      this.data.isEmpty=false;
    }
    this.setData({
      movies: totalMovies
    });
    // 计数器,数据绑定成功后才进行累加
    this.data.totalCount += 20;
  },

  onReady: function (event) {
    // 动态设置导航栏标题
    wx.setNavigationBarTitle({
      title: this.data.navigateTitle,
    })
  }
})

设置loading状态

以上我们完成了更多数据的加载,但是只是这样的话,体验还不够良好,我们需要在数据加载时提示用户一个loading状态,这样体验起来就没那么生硬。

有几个API都可以实现这个loading的效果,我这里使用的是wx.showNavigationBarLoading(),以下是关于交互反馈API的官方文档地址:

https://mp.weixin.qq.com/debug/wxadoc/dev/api/ui.html#wxshownavigationbarloading

编辑more-movie.js文件中的onScrollLower以及processDoubanData方法,在方法代码的末尾加上以下内容:

onScrollLower: function (event) {
            // 其他代码忽略

    // 设置loading状态
    wx.showNavigationBarLoading();
},

processDoubanData: function (moviesDouban) {
            // 其他代码忽略

    // 结束loading状态
    wx.hideNavigationBarLoading();
},

通过这两个API就简单的实现了数据加载时提示loading状态。


实现下拉页面重新刷新数据

几乎所有的app里都有下拉页面重新刷新数据的功能,所以我们也希望有一个这样的功能。不过目前有一个小问题,我们是使用scroll-view组件来实现下滑加载更多数据的,但是130400版本更新后却导致下拉刷新和scroll-view不能同时使用。

导致onPullDownRefresh事件函数无法执行的原因是页面里包含一个scroll-view组件。而scroll-view组件和onPullDownRefresh在130400版本里是冲突的。当我们在页面里滑动scroll-view时,只是滑动这个组件,不再可以触发onPullDownRefresh。当然,你还是可以在scroll-view区域外滑动页面执行onPullDownRefresh。什么意思呢?看下面的图:

点击箭头那块儿的空白部分依然可以执行onPullDownRefresh,但除此之外任何位置都不可以执行刷新事件。原因是因为,箭头的空白部分不属于scroll-view这个组件的区域,它是属于page页面的区域,page页面依然可以执行onPullDownRefresh。但如果是在scroll-view组件内部去拉动页面,则滑动的动作只对scroll-view组件有效,不再对page页面有效,自然就不会再触发页面的onPullDownRefresh。

解决方案如下(下拉刷新和加载更多同时存在的方法):

放弃使用scroll-view组件,改用view组件。那么既然放弃了scroll-view组件,上滑加载更多就不能再使用scroll-view的bindscrolltolower="onScrollLower"事件。

那么view组件如何监控上滑到底的事件?MINA在Page里还提供了一个onReachBottom事件,使用这个事件来监听页面上滑到底。

具体改动:

more-movie.js文件:

// 触发onReachBottom事件时加载更多的数据
  onReachBottom: function (event) {
    var nextUrl = this.data.requestUrl + "?start=" + this.data.totalCount + "&count=20";
    util.http(nextUrl, this.processDoubanData);

    // 设置loading状态
    wx.showNavigationBarLoading();
  },

将原本的onScrollLower方法更名成onReachBottom,方法的内容无需任何改动。

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>

完成以上的修改后,才能开始着手开始实现我们的下拉页面重新刷新数据的功能,首先我们需要编辑more-movie.json文件,增加如下内容,以开启下拉刷新功能:

{
  "enablePullDownRefresh": "true"
}

该配置语句的官网说明文档地址:

https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html

当下拉页面下拉刷新时会触发onPullDownRefresh事件方法,所以最后就是编辑more-movie.js文件,实现onPullDownRefresh方法,以及在processDoubanData方法里需要添加一句代码:

  // 当下拉刷新时会触发onPullDownRefresh方法,所以我们要实现它
  onPullDownRefresh: function (event) {
    var refreshUrl = this.data.requestUrl + "?start=0&count=20";
    util.http(refreshUrl, this.processDoubanData);

    // 清空movies里的数据
    this.data.movies = {};
    // 将totalCount归零
    this.data.totalCount = 0;
    // 并且改变isEmpty状态
    this.data.isEmpty = true;

    // 设置loading状态
    wx.showNavigationBarLoading();
  },

  processDoubanData: function (moviesDouban) {
          // 其他代码忽略

    // 停止刷新数据
    wx.stopPullDownRefresh();
  },

关于backgroundColor 到底设置的是哪里的颜色

很多人以为 backgroundColor 设置的是页面的背景颜色,而且官方文档上写的也不是很清楚,就写了个 “窗口的背景色” 。经过试验发现实际上 backgroundColor 设置的是我们下拉页面时的那个背景颜色,我们可以做一个简单的小实验,在more-movie.json文件中增加一行配置:

{
  "enablePullDownRefresh": "true",
  "backgroundColor":"red"
}

然后到more-movie页面中,然后下拉页面,可以看到背景颜色是我们设置的red红色:

或许不能说是下拉页面时的背景颜色,严格来说是Page页面底层下的背景颜色,也就是脱离了Page页面时裸露出来的页面背景。

原文地址:http://blog.51cto.com/zero01/2067094

时间: 2024-08-29 21:09:38

第五个页面:更多电影页面的相关文章

JavaScript网站设计实践(五)编写photos.html页面,实现点击缩略图显示大图的效果

原文:JavaScript网站设计实践(五)编写photos.html页面,实现点击缩略图显示大图的效果 一.photos.html页面,点击每一张缩略图,就在占位符的位置那里,显示对应的大图. 看到的页面效果是这样的: 1.实现思路 这个功能在之前的JavaScript美术馆那里已经实现了. 首先在页面中使用ul列表显示出所有的缩略图,然后使用JavaScript,for循环检查出当前点击的是哪一张图片,最后把这张图片给显示出来. 用到三个函数:显示图片函数.创建占位符预装图片.点击显示图片

iOS_20_微博『更多』页面

最终效果图: MoreViewController.m // // MoreViewController.m // 20_帅哥no微博 // // Created by beyond on 14-8-4. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "MoreViewController.h" @interface MoreViewController () { // more.plist根是字典

静态页面、动态页面和伪静态页面的区别

1.静态页面 优点:相对于其他两种页面(动态页面和伪静态页面),速度最快,而且不需要从数据库里面提取数据,速度快的同时,也不会对服务器产生压力. 缺点:由于数据都是存储在HTML里面,所以导致文件非常大.并且最严重的问题是,更改源代码必须全部更改,而不能改一个地方,全站静态页面就自动更改了.如果是大型网站有较多的数据,那会占用大量的服务器空间,每次添加内容都会生成新的HTML页面.如果不是专业人士维护比较麻烦. 2.动态页面 优点:空间使用量非常小,一般几万条数据的网站,使用动态页面,可能只有几

详谈Apache、Nginx和tomcat的区别以及处理静态页面和动态页面的方式

就目前来说,网站主要分为静态页面和动态页面,纯静态页面的网站已经比较少见了,大型网站一般使用的是静态页面+动态页面的建站技术,还有一部分网站是纯动态页面.负责处理这些页面的软件我们通常称之为web容器,是一种服务程序,负责处理客户端(浏览器)发来的访问请求,如果是静态页面会直接将文件内容呈现给客户端(浏览器),如果是动态页面会将其解析成静态内容之后再呈现给客户端(浏览器). 一.Apache.Nginx和tomcat的区别 ApacheApache HTTP Server(简称Apache)是A

页面元素与页面间的间隙

当我们做一个页面时,默认页面元素距页面左右上下都有一个很小的间隙.如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>三角形</title> </head> <style> .three{ width: 100px; height: 100px; border-style:

easyUI的iframe子页面操作父页面元素

曾经试过这样的方法 在iframe子页面获取父页面元素       代码如下:       $('#objId', parent.document); 这样可以获得父页面的元素,但是调用EasyUI的方法的时候,就会报错. 郁闷了很久很久,最终找到方案,写法的区别,如下: parent.$('# objId') 这样调用方法就不会报错 如: parent.$('# objId').tabs("add", { title: title, content: content, closabl

转 easyUI的iframe子页面操作父页面元素

曾经试过这样的方法 在iframe子页面获取父页面元素      代码如下:      $('#objId', parent.document); 这样可以获得父页面的元素,但是调用EasyUI的方法的时候,就会报错. 郁闷了很久很久,最终找到方案,写法的区别,如下: parent.$('#objId') 这样调用方法就不会报错 如: parent.$('#objId').tabs("add", { title: title,      content: content,      c

java web程序 登陆验证页面 4个页面人性化设置

到这里,快期末考试了,老师不讲课,我心里有苦不想说,也许没有考虑到老师的感受,让老师难堪了 但是我的行为已不再是我可以做的了.不可能了,我只是职业性的机械的做事了. 思路: 1.第一个是form表单,用户输入用户名和密码,点击登陆按钮 a.jsp 2.第二是验证页面,如果不是那个用户名和密码,则显示登陆失败或错误,点击链接重新登陆ok.jsp d.jsp 3.当用户为输入任何数据,即为空的时候,则提示用户先登录,c.jsp 第一个页面,就不写了 验证页面 ok.jsp ? 1 2 3 4 5 6

JavaScript:父页面与Iframe页面方法互调

父页面调用Iframe页面中的函数 以上是父页面中定义的iframe,注意添加name属性 在父页面中调用mapFrame的ShowMyLocation方法 Iframe页面调用父页面的方法 直接在Iframe内的页面通过window.parent.FuncName();调用即可 其中FuncName为方法名称