色婷婷五月综合久久中文_亚洲性爱毛片免费看_21国产精品喷潮白浆_国产精品无码亚洲精品2022_久久久亚洲国产精品性色

Menu
小程序資訊
小程序資訊
微信小程序開發(fā)系列分析《二》數(shù)據(jù)層
時間:2016-10-18 15:55:00
本文分三塊來講,網(wǎng)絡數(shù)據(jù)請求,文件操作,本地數(shù)據(jù)操作。涉及到的示例代碼地址:https://github.com/jsongo/weapp-tutorial-3

1、網(wǎng)絡請求

(1)需要一個數(shù)據(jù)接口來測試
上篇文章中的數(shù)據(jù),我們是寫死在page的data里的。實際應用中肯定不會這么干,只能是從后臺請求,或從本地存儲中獲取。
微信提供了一個接口用來發(fā)起請求:wx.request。而且它發(fā)起的請求,官方文檔中說,只能是https請求,且一個微信小程序,同時只能有5個網(wǎng)絡請求連接。

我們來修改一下上篇文章中用到的例子,我們把數(shù)據(jù)改成從36Kr那里獲取。稍微研究下36Kr網(wǎng)站的頁面,就會發(fā)現(xiàn)一個小接口,用來拉取列表數(shù)據(jù):
API:Get http://36kr.com/api/info-flow/main_site/posts?b_id=5053833&per_page=20&_=1475166251729
url參數(shù):bid表示上次列表拉到第幾條,那條的id;per_page表示要拉取多少條;最后的下劃線表示當前的時間戳,這個可以省略。
返回:json格式的數(shù)據(jù),結(jié)構(gòu)如下

36Kr返回列表數(shù)據(jù)
其中,當code為0時,表示沒有error,這時拿到的response.data.items就是我們要的數(shù)據(jù)列表,我們只取每一項里的幾個數(shù)據(jù)就可以了。請求的地址不是https,不過可以發(fā)現(xiàn),我們把地址改成https,也可以請求到數(shù)據(jù),說明36Kr后臺做了https的接入。

(2)發(fā)起請求
wx.request的用法其實跟ajax的調(diào)用很像。

wx.request({
  url: url,
  data: {},
  header: {
      'Content-Type': 'application/json'
  },
  success: function(res) {
    … // use res.data
  }
})
它有幾個主要的參數(shù):url指定請求地址;data帶上請求的數(shù)據(jù),可能是json數(shù)據(jù)也可以是字符串;header設置請求的頭部信息,如上面所示;method指定請求的方式,默認是GET,其它值有:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT;另外,success用來指定請求成功的回調(diào),fail是失敗的回調(diào),還有一個complete,成功或失敗都會回調(diào)。

以上代碼中,在success回調(diào)里拿到res是一個json數(shù)據(jù),格式如:{data: xxx} ,res.data就可以拿到服務器返回的數(shù)據(jù)。完整代碼可以參考github上的pages/index/index.js文件。

開發(fā)工具之前的破解版本,其實是發(fā)不了網(wǎng)絡請求的。因為微信在工具里做了一些安全限制,所以這里為了開發(fā),我們得再去破解開發(fā)工具。研究了下工具源碼,找到一個地方會對網(wǎng)絡請求的地址做驗證的,把它改掉就Ok。最新工具破解方法參考https://github.com/jsongo/weApp-ide ,有興趣的讀者可以到app.nw/app/dist/weapp/appservice/asdebug.js 文件中,找到下面這行代碼,把if條件改掉就可以用了,比較簡單。

破解網(wǎng)絡請求限制

(3)demo功能分析
簡單幾句話分析一下我們的36Kr新聞列表的demo。功能也挺簡單,打開時從網(wǎng)絡上請求36Kr的數(shù)據(jù)顯示成一個列表,點擊列表的每一項都可以進入查看這篇文章的正文內(nèi)容(只是個demo,所以就沒有去取內(nèi)容,直接拿每個列表項的summary字段去當正文)。列表頁在頂部下拉可以刷新列表,在最底部往上滑可以加載更多。

破解網(wǎng)絡請求限制

(4)demo數(shù)據(jù)分析
列表的生成邏輯跟上篇文章的一樣,只是數(shù)據(jù)的來源不同而已。主要代碼的結(jié)構(gòu)如下:

主代碼
data里定義了兩個屬性,一個是news數(shù)組,用來綁定列表數(shù)據(jù);refresh,用來決定上方的loading區(qū)域是否顯示,只有用戶在頂部下拉的時候,才會顯示最頂部的loading...區(qū)域,view中通過<view wx:if="{{refresh}}”>來綁定是否顯示,在<scroll-view>的bindscrolltoupper函數(shù)中用this.setData({refresh: true}) 把它顯示出來。然后在數(shù)據(jù)請求回來的complete方法中,再把它隱藏掉。這樣就簡單的實現(xiàn)了,下拉刷新的功能。當然體驗不是很好,讀者可以自己想慢慢地優(yōu)化軟件的體驗問題。

繼續(xù)分析下我們的demo代碼。
大家可能注意到了里定義了一個loading的屬性,它是用來記錄當前是否是在請求中,如果是就放棄請求。這主要用來防止同一時間發(fā)出多個請求。用戶幾個很快的動作可能會觸發(fā)了幾次數(shù)據(jù)加載,比如用戶在頂部下拉的時候,網(wǎng)絡不是很好,數(shù)據(jù)還沒返回,用戶可能會連續(xù)快速下拉好多次,這時用loading這個標識就可以過濾掉這些多余的操作。它在請求發(fā)出的之前設置為true,請求回來的時候,在complete回調(diào)中設置為false。

onLoad是生命周期函數(shù),只做了一件事件,就是調(diào)用reqData方法發(fā)起第一屏列表數(shù)據(jù)的請求。
bindItemTap綁定了每個新聞列表項的點擊事件,點擊后,把當前的數(shù)據(jù)傳入到App的globalData里,再切換到內(nèi)容詳情頁面,然后從globalData取出數(shù)據(jù)來顯示。在官方的文檔中沒有找到頁面間傳遞數(shù)據(jù)的其它辦法,筆者只想到兩種方式,一是通過剛討論的globalData,另一個是通過本地存儲來傳遞,這個在下面會再討論。

reqData方法封裝了數(shù)據(jù)請求的過程,第三個參數(shù)用來指定是append(底部加載更多)還是refresh(頂部下拉刷新),因為這兩個接口的請求地址等其它處理過程有些不太一樣。
formatData函數(shù),封裝了把請求返回的數(shù)據(jù)轉(zhuǎn)換成我們列表中用得到的數(shù)據(jù),修改一些字段,拼裝出每一個列表項數(shù)據(jù)。
renderData函數(shù)是我們重點要討論的,先看看實現(xiàn),30幾行,也不多:

renderData函數(shù)代碼
上方最開始的兩個if,用來驗證請求返回的數(shù)據(jù)。然后用formatData把它們轉(zhuǎn)化成我們可以用的數(shù)據(jù)列表。接著對appendOrRefresh進行判斷,如果是1的話,就是refresh;2的話,即為append,即在底部上滑時加載更多。都不是的話,就執(zhí)行默認的加載第一屏數(shù)據(jù),這個最簡單,只要setData把數(shù)據(jù)設置到綁定列表的news這個數(shù)據(jù)段就可以了。而且對于加載更多,和刷新,這兩個動作,則稍微復雜些。

先來看下appendOrRefresh,就是refresh,頂部下拉刷新。讀者思考一下,其實就是把新數(shù)據(jù),追加到原this.data.news列表里,由于index發(fā)生了變化,所以每一項的數(shù)據(jù)也會跟著變化,微信的文檔中沒有給出相應的解決方案,只能是整體更新整個列表,這會造成整個列表界面的整體刷新,效率會很低,希望后續(xù)MINA框架會有優(yōu)化。當然,聰明的讀者可能會想到優(yōu)化的方案,其實可以在這個時候,把新數(shù)據(jù)列表的前10項設置給this.data.news,反正用戶是在列表的頂部,第一屏也看不完這么多條。其它的數(shù)據(jù)則先存儲到本地,等用戶往下滑動的時候,再去檢查本地存儲是否有需要的數(shù)據(jù)。這要用戶去做一些標記的邏輯,下面會講到相關邏輯的實現(xiàn)。

再來看看底部上滑時加載更多,用過react的讀者應該都知道facebook提供了Immutable庫來實現(xiàn)局部刷新,但這個在微信小程序的開發(fā)中還不知道怎么整合。不過沒關系,我們有辦法。官方文檔中有一句話提示了一種解決方法,它上面的例子是:

    this.setData({
      'array[0].text':'changed data'
    })
看到這個,有沒有突然靈光一閃的感覺?沒錯,setData可以對數(shù)據(jù)進行局部的更新。所以我們的問題就得到了解決,其實也就是往this.data.news數(shù)組追加新數(shù)據(jù)而且不引起系統(tǒng)覺得整個數(shù)據(jù)都變了。如果只是簡單的setData({news: newArr}) 這樣用newArr來賦值,肯定不行,因為在內(nèi)存的地址都變了。這里要實現(xiàn)的核心目標是,保持news在內(nèi)存中的地址不變,MINA才不會去刷新整個列表。這個道理可能用過react的讀者會比較好理解一些。。這里筆者就假裝所有的讀者都已經(jīng)理解了(不理解的話就跳過吧,以后再回來看吧)。我們可以做一個for循環(huán),用this.setData方法傳入'array[xxx]': newItemXXX就行了。不過js里對json數(shù)據(jù)賦值時,key是不能用'array['+index+']'這樣的方式來做的,會報錯。所以可以像上面的代碼一樣用es6的語法,用[ ]中括號把key包起來。也或者也可以在上面定義一個變量newData,用newData['array[' + index + ']'] = newItemXXX這樣的方式來賦值也行,再this.setData(newData)就可以了。
這個知識點講的比較細些,有點啰嗦了。這一系列的文章是針對各種基礎的開發(fā)者,所以講得詳細些。

(5)接入列表刷新的接口
現(xiàn)在頂部下拉實現(xiàn)更新,就差一個接口了。上面第一屏的數(shù)據(jù)和底部上滑加載更多的數(shù)據(jù),我們有同一個接口可以獲取,那刷新呢?

于是我們再去36Kr網(wǎng)站上找找,可惜的是沒找到相應的刷新接口,不過找到了另一個替代品:
API: Get http://36kr.com/api/newsflash?b_id=26330&per_page=20&_=1475202501776
參數(shù)跟返回,跟本文介紹的第一個接口一樣,不再贅述。這個接口用來取新聞快訊,沒有圖片,比較麻煩,本文只做demo演示,所以這些都不是重點,我們就暫且拿接口里的user的頭像來當新聞圖片吧。36Kr網(wǎng)如若看到本文,希望不要計較這些,這些接口誰都可以從網(wǎng)頁請求中很容易得得到,本文只用它們來做一些demo演示,不做任何商業(yè)用途。當然如果讀者本人有后臺開發(fā)的能力,也可以自己寫個接口來做demo的數(shù)據(jù)源。

到這里,我們已經(jīng)實現(xiàn)了大部分功能,通過綁定事件來實現(xiàn)滑到詢問時,加載各種數(shù)據(jù),整個流程,從打開->加載數(shù)據(jù)->顯示列表->用戶操作時刷新或加載更多數(shù)據(jù)->點擊查看正文,小麻雀就已經(jīng)長了整個雛形了。

2、websocket和文件上傳下載

本文重點在數(shù)據(jù)層,websocket的知識點,在后面有一篇文章會專門討論,這里先簡單一句話帶過。
而文件也是數(shù)據(jù),在本文的討論范圍之內(nèi),下面分析兩個基本操作。

(1)文件上傳
其實也是一個post請求,微信封裝了兩個接口,wx.chooseImage選擇文件,和wx.uploadFile指定上傳的參數(shù),這兩個接口一起完成了文件上傳的動作。貼一個官方給的demo讀者自己看就行了,很簡單,也沒什么好分析的。要測試的小伙伴需要自己搭個后臺并像網(wǎng)頁正常的form文件上傳一樣,接收相應的參數(shù)和file data再寫入文件就ok。


(2)文件下載
調(diào)用wx.downloadFile接口,指定路徑和文件的類型,就可以拿到文件,這時微信會幫你把文件保存在一個臨時的目錄,小程序退出時它就會被清掉。如果這是一個比較重要的文件,以后還會用的話,請開發(fā)者一定要調(diào)用wx.saveFile方法把文件保存到比較持久目錄,微信不會隨意把它清理掉。保存時也不需要指定要保存到哪里,微信會在保存成功后,在回調(diào)里傳回給你它保存的路徑。

downloadFile的文件只能是image/audio/video這三種類型,即圖片、音頻和視頻文件。
在開者應用的時候,你可能會想保存登錄用戶的頭像等文件信息,這就可以用到上面的saveFile的方法,不過也要先調(diào)用wx.downloadFile先存到臨時目錄,因為saveFile只支持從臨時目錄保存到永久目錄。

不過在測試downloadFile的時候,發(fā)現(xiàn)success一直沒有被回調(diào),跟蹤了下代碼,發(fā)現(xiàn)到底層源碼在WeixinJSBridge.invoke(‘downloadFile’…)的時候就沒反應了,可能要到真實的手機環(huán)境中才能使用,也或許目前的這個開發(fā)用的IDE有點問題。

3、本地存儲

也是數(shù)據(jù)緩存。微信給每個小程序分配了5M的存儲空間,對這個緩存的操作,其實跟H5的localStorage操作是一樣的。

微信提供了三個主要的接口, wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync),括號里面的是方法是同步的方法,括號外面的方法是異步讀寫的方法。這兩類方法調(diào)用時傳入的參數(shù)大體差不多,只是異步的是通過傳入回調(diào)函數(shù)的方式來取到數(shù)據(jù),而同步的方法是直接返回數(shù)據(jù)。

(1)存入
wx.setStorage,參數(shù)是個json,字段有key指定存儲的鍵值,data指定存儲的值,如

wx.setStorage({key: 'name', data: 'jason'});
同時 還可以傳入success、fail和complete來取得數(shù)據(jù)或錯誤信息。
而wx.setStorageSync比較簡單,參數(shù)是直接傳的,如:

wx.setStorageSync('name', 'jason');
存入的data數(shù)據(jù),可以是字符串,也可以是json格式的對象Object。如果存的是json,取的時候,也會是json格式的。這個用起來會非常方便。

存入的數(shù)據(jù),可以在調(diào)試工具的Storage里看到,如上圖。

(2)取出
一樣,wx.getStorage也是傳入json,字段只要帶一個key字符串就行,通過字段success回調(diào)來取得參數(shù)。
而wx.getStorageSync就非常簡單,直接就可以取到返回值。

var value = wx.getStorageSync('key');
(3)刪除
wx.clearStorage()或wx.clearStorageSync(),直接調(diào)用就成。不過調(diào)用這個方法要注意,它會清掉所有的數(shù)據(jù)。
那要怎么刪除單個key的數(shù)據(jù)呢?很簡單,就是通過setStorage或setStorageSync,把data設置成null就可以把數(shù)據(jù)清掉了,讓它不占空間就可以了。

為什么要分同步和異步呢?
1是在存儲的數(shù)據(jù)比較大的時候,同步方法會引起界面的卡頓,所以用異步好些,不影響界面。
2是異步方法的錯誤處理,是fail回調(diào),出錯一般是通過fail傳出來的。而同步方法要加上try catch才能避免程序異常中斷。
不過同步比異步在使用的時候簡單很多。如果用戶在存儲的數(shù)據(jù)很小的時候,基本確定不會有什么邏輯錯誤,可以直接用同步方法。
但如果覺得你的應用有可能會達到5M的空間的時候,再存就會拋錯,這時同步方法就要注意try catch。
咨詢
微信掃碼咨詢
電話咨詢
400-888-9358