Day8-微信小程式實戰-交友小程式-首頁使用者列表渲染及多賬號除錯及其點贊功能的實現
在這之前已經把編輯個人的所有資訊的功能已經完成了
之後先對首頁的列表搞動態的,之前都是寫死的靜態
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這個雲函式寫成一個通用的方式
其中雲函式入口函式
exports.main = async (event, context) => { 這個裡面的event就是前端傳參過來的物件了 就訪問 event.colletion,然後不用where而是用doc 再把event的doc也傳進來,這 ***小知識點:ES6的擴充套件運算子 。。。 (三個點)更新成功了之後,就可以返回結果到前臺了
這個就是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) } }View Code
把雲函式寫好之後,這個時候雲函式還是在本地,要把這個雲函式傳到雲開發平臺上
上傳了之後一定要去雲平臺-》雲函式中去檢查一下
之後就可以呼叫這個雲函數了
再回到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函式中是用全域性的,不能寫死,所以運算的規則就通過前端傳過去
為了以後其他的頁面也有更新功能的話做準備了
&n