6.1 跳转到文章详情页面
6.1 跳转到文章详情页面
首先新建文章详情页面。在app.json的pages数组下新增页面路径:
"pages/post/post-detail/post-detail"
保存后,开发工具会自动生成post-detail页面的4个文件。首先要实现的是从post文章页面通过点击跳转到post-detail详情页面。
在post.wxml中的block代码块里注册一个事件。
代码清单 6-1 注册跳转文章详情页面事件 post.wxml
<block wx:for="{{postList}}" wx:for-item="item" wx:for-index="idx">
<template catchtap="onTapToDetail" is="postItemTpl" data="{{...item}}"/>
</block>
以上代码仅仅在template上增加了一个catchtap。接着,在post.js中编写这个事件的响应函数onTapToDetail。
代码清单 6-2 跳转文章详情页 post.js
import{DBPost}from'../../db/DBPost.js';
Page({
data:{ },
onLoad:function(){
var dbPost = new DBPost();
this.setData({
postList:dbPost.getAllPostData(),
});
},
onTapToDetail(event){
wx.navigateTo({
url: 'post-detail/post-detail',
})
}
})
添加完onTapToDetail函数后,保存运行,并在文章列表页面点击任意一篇文章。没有任何反应,页面也没有跳转。为什么会这样?
6.2 不要在template上注册事件
6.2 不要在template上注册事件
那么在block标签上注册可以吗?来试试
同样不可以,因为block也会在编译后“消失”。
那么,我们只有在template的外部增加一个view,将template给包裹起来,并将catchtap事件注册到view组件上。
代码清单 6-3 用view包裹template模板 post.wxml
<block wx:for="{{postList}}" wx:for-item="item" wx:for-index="idx">
<view catchtap="onTapToDetail">
<template is="postItemTpl" data="{{...item}}"/>
</view>
</block>
保存后,点击5篇文章中的任意一篇,就可以正确地跳转到post-detail文章详情页面了。
6.3 页面间传递参数的3种方式
6.3 页面间传递参数的3种方式
上一小节中,我们实现了从文章列表页面跳转到文章详情页面。要正确展示文章详情页面的内容,首先需要将文章的id号由post页面传递到post-detail页面,这样,post-detail页面才能知晓它要显示哪篇文章。
这涉及页面间的参数传递与通信。目前,在MINA框架中有以下几种参数传递方式:
(1)使用全局变量(关于全局变量,本书后面的章节中会讲到)。
(2)使用缓存。
(3)通过页面导航url的query参数传递。
基本上参数的传递只有以上3种方式,其他的比如像事件信号的传参方式(一个页面emit发送信号,一个页面on监听信号,这种在AngularJS里很常见的传参方式,小程序是不能天然支持的),其实都是这些基本思路的变种。
全局变量我们将在后面讲到,至于缓存的传参方式,开发者在学习完缓存后应该很容易想到。其实,使用缓存数据库存储data.js初始化数据,又在post.js中读取缓存数据,这其实就是页面间的参数传递。仔细想想,是不是这样?
(1)、(2)两种都涉及全局变量,笔者个人不推荐这种污染全局的传参方式,而且我们的需求仅仅是两个页面间传递参数,完全不需要干扰全局。所以,选用方法3来做页面间的参数传递。
6.3.1 组件的自定义属性
再来整理下思路。要将postId由post页面传递到post-detail页面,首先需要在post.js中获取到postId,随后再将postId附加到代码清单6-2中的wx.navigateTo的url中。
要想在post.js中获取到postId,就必须知道当前点击的文章是哪一篇文章。我们首先将postId绑定到每一篇文章的wxml中,使postId成为文章wxml的一个属性。注意,postId已在5.13小节中加入到data.js文件里。
绑定postId的方法很简单,就如同绑定文章的date、title等属性一样。post.js文件的代码无须任何改动,只需要对post.wxml文件做一下改动即可。
代码清单 6-4 绑定postId post.wxml
<block wx:for="{{postList}}" wx:for-item="item" wx:for-index="idx">
<view catchtap="onTapToDetail" post-data-id="{{postId}}">
<template is="postItemTpl" data="{{...item}}"/>
</view>
</block>
6.3.2 通过dataset获取组件自定义属性
修改post.js文件中的onTapToDetail函数如下:
代码清单 6-5 获取post-item-id post.js
onTapToDetail(event){
var postId = event.currentTarget.dataset.postId;
console.log("postId");
wx.navigateTo({
url: 'post-detail/post-detail?id='+postId,
})
}
上述代码中,我们通过event.currentTarget.dataset.postId,这段代码成功地拿到了当前文章的postId。
event事件对象是由MINA框架在调用onTapToDetail函数时传递的参数。在event事件对象中,有一个currentTarget代表事件绑定的当前组件。
重点是dataset对象,dataset对象里包含当前组件中所有属性名以data-开头的自定义属性值。我们在代码清单6-5中的view上绑定了data-post-id,所以通过dataset.postId将可以拿到当前组件的postId。
组件自定义属性名有以下规则:
必须以data-开头。
多个单词由连字符“-”链接。
单词中最好不要有大写字母,如果有大写字母,除单词第一个字母外,其余大写字母将被转化成小写。
在js中获取自定义属性值时,多个单词将被转化驼峰命名。
看起来很复杂,但举几个例子就非常清楚了,如表6-1所示。
表6-1 组件的属性定义
在获取到postId后,我们将postId附加在导航Url的query参数中:
6.3.3 获取页面参数值
再来看看如何在post-detail页面中获取postId,在post-detail.js文件中添加以下代码:
代码清单 6-6 获取页面参数 post-detail.js
// pages/post/post-detail/post-detail.js
Page({
data:{},
onLoad:function(options){
var postId = options.id,
},
}
)
接受post页面传递参数的方法是通过post-detail页面onLoad函数里的options参数来获取。options参数是由框架传递的。
注意,这里options.id中的“id”必须同代码清单6-6中navigateTo中url的query参数名称保持一致。比如,在query参数中使用的是name=postId,则这里要相应地使用options.id编译时设置初始化页面及参数
6.4 编译时设置初始化页面及参数
现在我们主要的代码编辑工作集中在post-detail这个页面。但每当保存刷新小程序后,项目都将从欢迎页面启动。我们不得不依次点击启动页面、文章列表,才能进入到文章详情页面以预览文章详情的效果,这相当的麻烦。
当然可以按照4.1小节中的方法,将post-detail页面设置为app.json中pages数组的第一项,但post-detail还需要传入一个postId的参数才可以正确地运行,且手动来回更改pages数组非常麻烦。
小程序在122100版本中增加了编译选项,在此版本中,官方提供了一个“自定义编译”功能,可用于定义小程序的启动页面,如图6-3所示。
122100版本后,“编译”这里变成了两个选项,请仔细查看。上面一个图标是默认编译,下面的图标是自定义编译,点击下面的图片将弹出如图6-4所示的界面。
图6-4 自定义编译选项
启动页面一栏中将路径设置为post-detail页面的启动路径:
pages/post/post-detail/post-detail
页面自定义参数类似于url中的query参数,设置id=2将可以在页面中通过onLoad函数中的options.id获取到这个值。
设置完成后,必须勾选【使用以上条件编译】这个选项。
保存刷新页面,项目将直接进入post-detail页面,不再出现welcome启动页。同时,我们发现,以这种方式打开的post-detail页面无法再返回到post页面,因为不是通过post页面导航到post-detail页面的。
可以通过“&”连接多个页面参数,比如id=2&name="MR.L",同时将两个参数传递到post-detail页面中。
有了以上功能,就可以非常方便地调试post-detail页面。
如果想恢复默认的启动页,只需去掉【使用以上条件编译】选项即可。