手把手教你搭建答题活动小程序系列文章,第一阶段为界面设计篇,分别描写了如何搭建答题小程序界面。
现在已经进入第二阶段,功能交互篇。而上一篇文章描写了,如何用云开发实现查询题库功能。其实说白了就是相当于,前后端分离架构中的异步请求。
这一篇紧接着上一篇,聊聊用云开发实现查询题库功能后要做的事情。通俗来说,就是拿到题目数据后,接着要干什么。
软件架构:微信原生小程序+云开发
版本持续迭代中...
聊聊用户体验
这里先插个题外话。
用户体验好不好,真的重要吗?如何做好答题小程序的用户体验呢?
我问你一句,你敢答应吗,第一个问题留给你来思考一下。我来聊聊第二个问题,我个人认为,从做好一个个的界面交互细节开始。
举个栗子,就拿我这个答题小程序,项目里的其中一个界面交互细节,来简要聊聊吧。
1)看,首先还是快速看一下官网技术文档:
wx.showLoading(Object object)显示 loading 提示框;
wx.hideLoading(Object object)隐藏 loading 提示框;
2)用,我使用了上述的小程序原生的API,具体使用聚焦到发送异步请求的函数:
// 获取题库 getQuestionList() { // 显示 loading 提示框 wx.showLoading({ title: '拼命加载中' }); // 发起请求 activityQuestion.where({ true: _.exists(true) }) .get() .then(res => { // 隐藏 loading 提示框 wx.hideLoading(); }) }
当获取数据的时候,这个加载提示是在告诉用户,题目数据正在加载中,请耐心等待一下,很快就好了。
// 显示 loading 提示框 wx.showLoading({ title: '拼命加载中' });
当数据获取成功后,就隐藏这各提示,相当于告诉用户,好了,你可以开始做题了。
// 隐藏 loading 提示框 wx.hideLoading();
言归正传
拿到数据后要干什么?如何做?
实现动态数据绑定,其实,概括起来就三步走:
1)先通过 Collection.get 来获取题库集合里的题目数据;
2)再使用setData函数将题目数据从逻辑层发送到视图层;
3)再Mustache 语法(双大括号)将变量包起来,实现动态数据绑定。
界面演示
1)获取数据
防火安全知识专项学习与竞答
2)同步更新
防火安全知识专项学习与竞答
3)填充到答题界面
源码解读
数据绑定
test.js
Page({ /** * 页面的初始数据 */ data: { questionList: [], // 题目列表 index: 0 // 当前题目索引 } })
test.wxml
<view class="page"> <view class="padding-top text-center"> 第<text class="text-bold text-xl">{{index+1}}</text>题 共<text class="text-bold text-xl">{{questionList.length}}</text>题 </view> <view class='page__hd padding'> <view class="page__title"> <text class="text-bold">【单选题】</text> {{questionList[index].question}} </view> </view> <view class="page__bd"> <radio-group class="radio-group"> <label class="radio my-choosebox" wx:for="{{questionList[index].option}}" wx:for-index="key" wx:for-item="value" wx:key="index"> <radio value="{{key}}" checked="{{questionList[index].checked}}" /> <text class="margin-left-xs">{{value}}</text> </label> </radio-group> </view> <view class='page_ft flex padding flex-direction'> <button class="cu-btn bg-red round lg" wx:if="{{index == questionList.length-1}}">提交</button> <button class="cu-btn bg-red round lg" wx:else>下一题</button> </view> <view class="mw-weixin text-center text-gray padding-top"> <text class="icon-weixin"></text> meng674782630 </view> </view>
WXML 中的动态数据均来自对应 Page 的 data。
其中,wx:for实现列表渲染:
<label class="radio my-choosebox" wx:for="{{questionList[index].option}}" wx:for-index="key" wx:for-item="value" wx:key="index"> <radio value="{{key}}" checked="{{questionList[index].checked}}" /> <text class="margin-left-xs">{{value}}</text> </label>
其中,wx:if和wx:else实现条件渲染:
<button class="cu-btn bg-red round lg" wx:if="{{index == questionList.length-1}}">提交</button> <button class="cu-btn bg-red round lg" wx:else>下一题</button>
更新视图
setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。
activityQuestion.where({ true: _.exists(true) }) .get() .then(res => { let data = res.data || []; // 将数据从逻辑层发送到视图层,通俗的说,也就是更新数据到页面展示 this.setData({ questionList:data, index: 0 }); })
注意:
- 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
- 仅支持设置可 JSON 化的数据。
- 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
- 请不要把 data 中任何一项的 value 设为 undefined ,否则这一项将不被设置并可能遗留一些潜在问题。