微信小程序开发入门之共享账本(十三)
接着上一篇
(备注:微信小程序的wxml文件相当于HTML文件,wxss文件相当于CSS文件,js文件就是JavaScript文件,数据库为NoSQL数据库,数据库脚本语言也同NoSQL)
(ps:区块链最近可真是火,但是也不能因此乱了方寸,做事要有始有终不是,等写完小程序的文章再和大家共同学习下区块链的知识吧)
在开启本篇之前,还是先回顾下之前不足的地方。
翻看代码的时候发现了一个问题,在index.js的onLoad函数中我们调用了系统方法wx.getSetting和wx.getUserInfo,仔细想想这两个方法其实都是不必要去调用的,关于授权的工作应该都放在welcome页面中去做,到了index页面,我们只需要关心用户信息和默认账本的初始化有没有成功
所以,我们可以把index.js中的onLoad函数大大简化,只留下一行代码
onLoad: function (options) {
this.verify()
}
即可
运行验证一下
undefined?
这是因为我们去掉了onLoad中的wx.getSetting和wx.getUserInfo,所以name字段没有赋值,下面我们要从verify的返回中取用户的信息
还记得verify云函数的内容吧,去查询user集合和acctBook集合,如果有一个没数据就返回失败,否则返回账本信息。其实我们用户信息也查了的,一起返回,岂不快哉
修改verify云函数成功返回的那一句为
return Promise.resolve({userInfo:r1.data,acctBookInof:r2.data})
这样一次验证过程中用户信息和账本信息就都有了
然后在index.js的data中删掉name字段,新增下面两个字段
userInfo:{}, acctBookInfo:{},
分别存储用户信息和账本信息
再将verify函数的返回成功then部分内容稍加改动
this.setData({
userInfo:res.result.userInfo [0],
acctBookInfo:res.result.acctBookInfo [0]
})
wx.showToast({
title: "欢迎你," + res.result.userInfo [0].name,
image: '/images/smile.png'
})
保存了用户和账本信息,wx.showToast的名称从返回中取。
注意一点,因为返回的都是数组,所以要取第一个,别漏了[0]
编译运行,一切正常
对于记录存储,之前我们是用一个临时集合tempAcctBook来记录,其实也可以
但是将所有记录存在一个表里肯定会导致表的数据过大,影响查询效率,所以我们可以依照实际情况建多个集合,再根据账本名称或者其他字段进行分库(就是对账本名称设计一个算法,比如取模,然后根据结果把记录存到对应的集合中),并且隔一段时间对集合做一次备份
比如建四个集合bill0,bill1,bill2,bill3,然后根据账本名称的hash值模4进行分库(或者用一致性hash算法来分库,更优秀)
当然,这些都是数据量大的情况下需要考虑的,自用的话请忽略
这里我们就建一个集合就行了,取名bill1
bill1的结构设计如下
我们在调新建记录组件时也不需要再传acctBookName了,因为账本名称是后台自动计算得到的,现在我们需要传一个acctBookId来唯一标识一笔记录属于哪个账本,所以把newBillSteps.js中property字段修改一下
properties: {
accountBookId:{
type:String,
default:''
}
}
在generateBill函数中加上acctBookId字段
acctBookId:this.data.accountBookId
然后将complete函数调用云函数addBill传入的acctBookName删除
let result = wx.cloud.callFunction({name: 'addBill',data: {
bill: bill
}
})
并将addBill云函数中的集合名称写成固定的bill1
db.collection('bill1')
最后在index.wxml中传入acctBookId
<newBillSteps wx:if="{{showNewBillWindow}}" bind:finished="onNewBillFinished" accountBookId="{{acctBookInfo._id}}"></newBillSteps>
编译运行,新增记录
查看云数据库,记录存储成功
然后我们在index.js中添加对集合bill1的实时监控,当bill1的内容发生变化时,可以实时在页面中表现出来
先定义两个个全局变量
const db = wx.cloud.database()
const watcher = null
db是数据库对象,watcher是我们将要添加的监听器引用
然后添加一个函数setWatcher
setWatcher: function (acctBookId) {
console.log('setWatcher acctBookId:',acctBookId)
let that = thisthis.watcher = db.collection('bill1').where({
acctBookId: acctBookId
}).watch({
onChange: function (snapshot) {
that.setData({
billItems: snapshot.docs
})
},
onError: function (err) {
console.error('监控发生错误', err)
}
})
}
该函数的作用是对指定的集合和条件下符合的数据进行监听(watch),在数据发生变化时会触发onChange事件,我们可以在此事件内对相应变化进行反应
这里暂时未进行特殊判断,每次都将全量的数据snapshot.docs赋值给billItems,这样做也没问题,因为我们也不需要对发生变化的数据有任何特殊操作,只是数据量大的情况下可能会影响效率,暂时可以不考虑这个问题,后面会改进
最后在verify函数成功的回调中加上一句
this.setWatcher(res.result.acctBookInfo[0]._id)
来启用监听
编译运行程序,已有数据会自动加载进来
如果从云端数据库删除这条数据,显示也会同步更新
OK,今天就先到这,下一篇继续讲数据监听问题,同时要加个新功能