在这之前已经把编辑个人的所有信息的功能已经完成了
之后先对首页的列表搞动态的,之前都是写死的静态
1、之前都是把好友写死的,现在就在js里面定义一个数组,用循环来动态的绑定
在onReady中定义,取真实的数据给定义的列表数组list
通过调用 db.collection('users').get() 这里没有加其他的限制,得到的就是所有的数据了,拿到全部的数据之后就会触发then方法了
用then返回的res中有一个data的列表集合,有一个注意的点就是,这样子读取是吧数据库中的数据的全部字段,但是我们需要用的只是
用户的头像和点赞数、用户昵称,其他的数据其实是不需要的
可以加一个field方法,可以要求返回的字段是哪些的
可以看到是只有一个用户,我们为了模拟的话,就可以多账号进行调试,
1、创立多账号
①首先这个多账号的一定要是测试号,所以先进入微信的管理后台 https://mp.weixin.qq.com/
②进入 【成员管理】添加项目成员
③回到微信开发者工具中-》工具-》多账号调试-》可以通过添加虚拟测试号来进行测试的,不用真实的微信号都可以
之后就是对点赞的功能进行设计了(就可以在index.wxml中给点赞的小心上加一个点击事件即可了
(小细节在小程序中规定,在客户端中读取用户列表的时候,一般不会把整个数据库的用户都读取出来的,是有一个限制的
一般都是把前二十条数据给读取出来的,如果数据一多的话,一般都是进行分页处理了--一般都是用数据库中的collection.skip和collection.limit,这两个东西一起配合的话就可以做下拉加载的功能了)
由于这个点赞是要对找到用户的id地址的,所以在wxml中给点赞这个图标加上一个id自定义属性的挂载
data-id="{{ item._id}}"
这个东西的用处就是,在点击这个心心的时候就可以拿到这个自定义的属性id了
通过把handleLinks(ev)函数中把ev打印出来发现,这个自定义属性id 的位置在
ev.target.dataset.id
console.log就是用来测试的,如果没效果的话,一般都是直接在点击事件后面通过promise 的then把res打印出来看看情况是怎么样的
***有时候这些点击事件无法触发的话,就可以在检查一下样式,可能这个区域在前端显示是在这里,但是实际上是在其他的地方,
也就是布局引起的问题了
可以看到这里就是碰到的是点赞的这个图标,但是这个样式是在左上角进行了渲染的
这个时候为了演示把,就把自定义属性,和点击事件放在点赞图标还有点赞数包含的这个text里面了
<text bindtap="handleLinks" data-id="{{ item._id}}" > <!-- 点赞图标 --> <text class="iconfont icondianzan" ></text> <!-- 点赞数 --> <text>{{ item.links }}</text> </text>
改完之后,再点击心心或者是数量,就可以正常的进行点赞了
但是发现只有给自己点赞的时候才可以改变点赞的数量,而改其他人点赞的时候就改不了
比如:
这就是一个权限的问题了也就是只能改自己的数据(点赞数)改不了别人的数据l
因为在小程序端中,由于用户可以直接对数据库进行操作,所以会有一定的风险,所以就通过这个访问权限来进行了限制
那?
怎么修改别人的数据呢?---这个操作就要在服务端来进行操作了! 也就是在云函数中去完成一个云函数的操作了
下面就是讲解 如何在 服务端来对数字字段来进行更改!
二、点赞功能实现与update云函数
由于要在服务端来做的话,就可以把这一块的部分代码删掉了
handleLinks(ev){ let id = ev.target.dataset.id; db.collection('users').doc(id).update({ data : { links : 5 } }).then((res)=>{ console.log(res) }); }
需要新创一个云函数(新建一个node.js云函数
这些默认的结构都是可以删掉的了
之后就是参考 微信开放文档 云开发-》SDK文档->数据库-》collection->update-》示例代码demo
其中:这个就是指定了数据库的环境
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
然后就是在服务端拿到数据库db
const db = cloud.database()
然后可以在示例代码中看到async这个异步的操作
直接复制 try catch
try { return await db.collection('todos').where({ done: false }) .update({ data: { progress: _.inc(10) }, }) } catch(e) { console.error(e) }
return就是返回一个异步的数据,而catch就是返回错误信息
主要修改的就是 db.collecion()中要反问那个数据库表单,这里不能写死为users,因为可能其他的地方也是要用到更新的这个功能的
所以最好就是把update这个云函数写成一个通用的方式
其中云函数入口函数
更新成功了之后,就可以返回结果到前台了
这个就是update云函数中js文件的代码(传进去的doc实际上是用户的_id
// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() // 云函数入口函数 exports.main = async (event, context) => { try { return await db.collection(event.collection).doc(event.doc) .update({ data: { ...event.data }, }) } catch (e) { console.error(e) } }
把云函数写好之后,这个时候云函数还是在本地,要把这个云函数传到云开发平台上
上传了之后一定要去云平台-》云函数中去检查一下
之后就可以调用这个云函数了
再回到index.js 点赞的方法 handleLinkes方法中进行设置即可;
如果云函数没问题,可能是云函数里面定义的env出了问题,就可以写死了,传入自己的那个环境,就不用默认的那个环境了
【注意】修改了云函数记得要重新上传到云平台才行
(因为在服务端是不会受到数据库权限的限制的)
后面要优化的就是(上面的点赞是写死给多少links的,并且不能点完之后立马更新
可以把数据库的links读出来,+1之后再写入,但是这样的话就多了一个数据库的操纵了 ,但是数据库本身就提供了累加或者累减等运算的操作的
(这样的话就只需要一次的数据库读取即可了)
在开放文档 db.command里面就有很多的方法
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/database/command/Command.inc.html
示例代码 将一个 todo 的进度自增 10: const _ = db.command db.collection('todos').doc('todo-id').update({ data: { progress: _.inc(10) } })
为了在服务端不把运算给写死了,一般都是把运算直接通过前端来传入的
由于前端不认识下划线这种操作,因为前端要先解析,之后再把东西传到服务端的,所以就可以在前端给服务端传一个字符串的话
然后再在服务端解析即可
data : "{links : _.inc(1)}"
在前端把这个字符串传入到服务端中,之后就可以在服务端那边对这个字符串进行解析了
所以在update云函数中 就要对event.data这个传过来的数据进行判断,判断它的类型,是普通的还是字符串类型的,如果是字符串类型的话就要进行解析
用js里面的eval方法,它是把字符串转成 js 语句的
if(typeof event.data == 'string'){ event.data = eval('(' + event.data + ')') }
即可了(点一下心心就可以让点赞数+1)
后面有空的话,可以继续进行优化,也就是对一次的点赞数进行限制,或者是点一下加+1,再点一下就是取消了就-1了
后面就是要把点赞了之后,实时的把点赞数进行更新
可以看到给服务端那边上传之后,对数据库进行了更新之后,then返回的结果res,中有一个是updated==1,就可以进行if判断了
再用for循环对列表中的每一个元素判断,是不是现在被点击点赞的这个id
let updated = res.result.stats.updated; if(updated){ // 先用扩展运算符 克隆一份数组 let cloneListData = [...this.data.listData]; for(let i = 0;i < cloneListData.length ; i++){ if( cloneListData[i]._id == id){ cloneListData[i].links++; } } this.setData({ listData : cloneListData }); }
点赞数增加 就是通过_inc 但是在服务端中的update函数中是用全局的,不能写死,所以运算的规则就通过前端传过去
为了以后其他的页面也有更新功能的话做准备了