1. 程式人生 > >Day8-微信小程式實戰-交友小程式-首頁使用者列表渲染及多賬號除錯及其點贊功能的實現

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