8分钟

任务 5 评论列表功能实现

任务目的

目前新建评论的功能已经实现,但是已经创建的评论只是存储在数据库中,还没有在页面上进行展示。这一步的操作主要是将评论以列表的形式展示在主页,同时借助统计图表展示正面和负面的评论占比。为了快速实现完整的评论列表获取,此处需要构建一个新的云函数用于获取评论列表数据,并将获取到的所有数据一并返回到本地,再由本地页面对获取到的数据进行渲染。完成这一步的操作后,可以看到一个完整的主页,包含话题的统计信息,评论的展示列表,以及新建评论的功能模块。

任务步骤

1.功能预期效果展示

经过这一步的操作,我们希望能够完成如下功能:

  • 主页展示评论统计图表,以及具体的评论列表;
  • 点击任意评论,可以跳转到评论详情页;
  • 点击评论详情页的 “返回评论列表” 按钮,可以跳转回主页。

功能展示效果如下:

4-5-1 评论列表预期展示效果

接下来会介绍具体的实现步骤。

2.添加评论列表本地代码

(1)引入Vant相关组件。

构建评论列表的页面效果,需要用到Vant组件中的cell和cell-group。

此处的Vant组件需要在index的index.json页面引入,由于在 任务2 的第二步中已经完成了相关组件的引入,所以此处无需再进行额外操作。

(2)编写wxml页面代码。

接下来需要更新index页面的index.wxml文件,添加情感分析图和评论列表单元格对应的标签内容。具体添加的内容如下(文件中的其他内容不变):

【修改文件:index.wxml,所在页面:index】

<text class="title">话题:今天你开心吗?</text>
<!-- 上方内容无需修改 -->

<!-- ++++++++++新增内容++++++++++ -->
<view>
  <view class="sentiment" wx:if="{{Sentiment !== ''}}">
    <canvas class="sentimentCanvas" canvas-id="sentimentCanvas">
      <cover-view class="text">
      <cover-view class="center-text {{positiveCount<negativeCount?'negative':'positive'}}">{{positiveCount<negativeCount?"负面":"正面"}}</cover-view>
      </cover-view>
    </canvas>
    <view class="sentiment-number">
      <view class="sentiment-view">
        <block>
        <view class="groud positive-groud"></view>
        <text class="sentiment-text">正面评论 <text class="number">{{positiveCount}}</text></text>
        </block>
      </view>
      <view>
        <block>
        <view class="groud negative-groud"></view>
        <text class="sentiment-text">负面评论 <text class="number">{{negativeCount}}</text></text>
        </block>
      </view>
    </view>
  </view>
</view>

<text class="subtitle">评论列表(点击查看评论详情):</text>

<scroll-view class="comments" scroll-y="true">
  <block wx:for="{{comments}}" wx:key="_id">
    <van-cell-group>
      <van-cell bind:click="showDetail" data-id="{{item._id}}" title="{{item.comment}}" title-class="{{ item.sentiment == 'negative' ? 'isNegative' : 'isPositive' }}" value="详情" label="negativity: {{item.negative}}" center is-link />
    </van-cell-group>
  </block>
</scroll-view>
<!-- ++++++++++新增内容++++++++++ -->

<!-- 下方内容无需修改 -->
<van-cell-group>
......

上方的view标签中添加的内容,对应用户评论的统计图表,下方scroll-view标签中添加的内容为评论列表。

注:实际开发中需要注意,如果使用到Vant组件或类似的其他组件,一定要先在json文件中将其引入,否则页面上对应部分的内容无法正常展示。

(3)编写js页面代码。

接下来需要编写页面逻辑部分的代码。打开index页面的index.js文件,在原来的代码下面添加以下内容:

【修改文件:index.js,所在页面:index】

Page({
  ......
  // 上方内容无需修改

  // ++++++++++新增内容++++++++++
  // 生命周期函数--监听页面加载
  onLoad: function (options) {
    // 更新页面的宽度信息,用于绘制图表
    this.setData({
      width: wx.getSystemInfoSync().windowWidth
    })

    // 倒序获取评论列表信息
    wx.cloud.callFunction({
      name: "getComments"
    }).then((res) => {
      this.setData({
        comments: res.result.data.reverse()
      })

      // 求出积极和消极的评论条数
      let count = 0
      let comments = res.result.data
      for (let i = 0; i < comments.length; i++) {
        if (comments[i].sentiment == "negative") {
          count += 1
        }
      }
      this.setData({
        "negativeCount": count + "条",
        "positiveCount": comments.length - count + "条",
        "Negative": Math.round(count / comments.length * 10000) / 10000
      })
      drawRing()
    })

    const that = this
    function drawRing() {
      const ctx = wx.createCanvasContext("sentimentCanvas", this)
      const width = 260;
      const lineWidth = 16;
      ctx.lineWidth = lineWidth;
      const rpx2px = (rpx) => (rpx * that.data.width / 750);
      const value = (that.data.Negative) * 2 * Math.PI;  
      ctx.beginPath();
      ctx.arc(rpx2px(width) / 2, rpx2px(width) / 2, rpx2px(width - 4 * lineWidth) / 2, 0, 2 * Math.PI);
      ctx.setStrokeStyle('#29cc85');
      ctx.stroke();
      ctx.beginPath();
      ctx.arc(rpx2px(width) / 2, rpx2px(width) / 2, rpx2px(width - 4 * lineWidth) / 2, 3 * Math.PI / 2 - value, 3 * Math.PI / 2);
      ctx.setStrokeStyle('#ff584e');
      ctx.stroke();
      ctx.draw();
    }
  },
  // ++++++++++新增内容++++++++++
})

对应的代码逻辑说明如下:

  • onLoad:监听页面加载,执行如下功能:更新页面宽度信息,调用云函数getComments(稍后创建)获取评论列表,统计积极和消极评论数,并在主页进行数据绑定,调用drawRing方法绘制统计图表。
  • function drawRing():绘制情感分析图表的函数,此函数会接收情感分析中的关键参数,结合分析结果绘制图表。

至此本地部分的代码已经编辑完毕,下一步将会构建获取评论数据的getComments云函数。

3.云函数实现评论数据获取

之前已经进行过云函数addComment的创建,这一步需要创建一个新的云函数getComments,调用数据库API,获取评论数据。

注:本地小程序也可以调用数据库API,但每次只能获取20条数据,需要添加额外的加载逻辑。此处希望通过一步操作获取全部数据,同时巩固学员对于云函数知识的掌握,所以将这一步的操作放在云函数中实现。

(1)创建云函数getComments

右键点击小程序目录cloudfunctions,选择新建 Node.js 云函数,创建一个名为getComments的云函数。

(2)通过云函数获取评论数据。

将云函数getCommentsindex.js文件替换为以下内容:

【修改文件:index.js,所在云函数:getComments】

const cloud = require('wx-server-sdk')
cloud.init()

// 创建数据库对象
const db = cloud.database()
exports.main = async (event, context) => {
  // 获取并返回集合中的所有数据
  return await db.collection('userComments').get().then((res) => {
    return res
  })
}

此处仅在原逻辑代码中添加了两处内容:

  • 创建数据库对象
  • 调用数据库API,获取并返回集合userComments中的所有数据

保存文件后,记得右键点击云函数getComments,选择 “上传并部署:云端安装依赖(不上传 node modules)” ,上传云函数后功能才会生效。

完成这一步的操作,再次访问小程序的主页,此时的评论列表已经可以正常展示,说明获取评论数据的功能实现。

4.点击评论跳转至详情页功能实现

在更新主页的index.wxml文件时,已经在单元格上绑定了点击的触发事件:点击单元格将会触发showDetail函数。但是目前此函数的功能还没有被添加,所以点击单元格后不会执行任何操作。

这一步的任务是添加点击单元格时执行的逻辑功能。

打开index页面的index.js文件,在文件底部添加showDetail函数执行的功能:

【修改文件:index.js,所在页面:index】

Page({
  ......
  // 上方内容无需修改

  // ++++++++++新增内容++++++++++
  showDetail: function (event) {
    // 获取点击的单元格对应数据id
    let id = event.currentTarget.dataset.id
    wx.navigateTo({
      url: '/pages/detail/detail?id=' + id,
    })
  }
  // ++++++++++新增内容++++++++++
})

点击评论单元格时,此函数会被触发,功能是获取单元格绑定的数据id,将其作为参数传递到评论分析页。稍后评论分析也便可借助此数据id调用数据库API,获取评论的分析数据并在页面上展示。

至此整个实验的小程序已经完成。