5

手把手教你搭建消防安全答题小程序-将用云开发获取到的题目渲染到答题页面

 2 years ago
source link: https://segmentfault.com/a/1190000040964250
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

手把手教你搭建答题活动小程序系列文章,第一阶段为界面设计篇,分别描写了如何搭建答题小程序界面。

现在已经进入第二阶段,功能交互篇。而上一篇文章描写了,如何用云开发实现查询题库功能。其实说白了就是相当于,前后端分离架构中的异步请求。

这一篇紧接着上一篇,聊聊用云开发实现查询题库功能后要做的事情。通俗来说,就是拿到题目数据后,接着要干什么。

软件架构:微信原生小程序+云开发

源码地址,获取源码,版本持续迭代中...

聊聊用户体验

这里先插个题外话。

用户体验好不好,真的重要吗?如何做好答题小程序的用户体验呢?

我问你一句,你敢答应吗,第一个问题留给你来思考一下。我来聊聊第二个问题,我个人认为,从做好一个个的界面交互细节开始。

举个栗子,就拿我这个答题小程序,项目里的其中一个界面交互细节,来简要聊聊吧。

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)获取数据
image.png

2)同步更新
image.png

3)填充到答题界面
image.png

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 ,否则这一项将不被设置并可能遗留一些潜在问题。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK