從點選事件看微信小程式的資料傳遞
最近用微信小程式做了一個電影類APP,業務邏輯不難,但在做最後一個頁面時遇到了一個詭異的問題,這個問題讓我對小程式框架裡的事件和資料繫結有了更深的認識。
問題是這樣的:
該小程式有4個頁面,分別是“影院熱映home”、“即將上映comingSoon”、“電影查詢search”和點選以上3個頁面中每條具體的電影條目會跳轉到的“詳情頁面detail”。
這個問題剛好出在從“影院熱映”點選電影條目到“詳情頁面”處,要麼無法顯示電影具體資訊,要麼點選不同條目總是顯示同一條電影的資訊。
因為從不同頁面點選電影條目,繫結的點選事件都會將頁面跳轉到對應詳情頁面,而詳情頁面的detail.wxml檔案是確定的。那麼無法正確顯示電影資訊,一定是detail.wxml檔案繫結的資料出問題了。
所以從detail.wxml的資料來源即detail.js找問題。
// pages/detail/detail.js
var subjectUtil = require("../../utils/subjectUtil.js");
Page({
data:{
movie:{}
},
onLoad:function(options){
// 頁面初始化 options為頁面跳轉所帶來的引數
this.loadMovie(options.id);
console.log(options);
},
loadMovie: function(id) {
wx.showToast({
title: '載入中' ,
icon: 'loading',
duration: 10000
});
var page = this;
//var id = wx.getStorageSync('id');
wx.request({
url: 'https://api.douban.com/v2/movie/subject/'+id,//需要傳遞具體的id才能載入電影;
header: {
'Content-type': 'json'
},
success: function (res){
var subject=res.data;//
subjectUtil.processSubject(subject);
page.setData({movie:subject});
},
complete:function(e) {
wx.hideToast();
}
});
},
})
wx.request()是微信小程式自帶的發起HTTPS網路請求的API,我所需的資源從url: ‘https://api.douban.com/v2/movie/subject/‘+id 獲取,這個API介面帶一個id引數,不同的電影有不同的id。所以詳情頁出問題代表資料來源出問題,資料來源出問題代表id出問題,現在的關鍵是看id出什麼問題。
要想了解id的問題,首先要知道id在哪裡,其次知道點選電影條目之後怎麼到詳情頁面去的。
從API介面請求回來的資源是一個物件,物件裡有大量的資料,比如圖片、評分等,id就是其中一個。
好了,已經知道id的位置,那這個id又是怎麼到detail.js中去的呢?
其實,這個id是繫結到任何一個頁面的WXML裡的。
<!--movieTpl.wxml-->
<template name="movies">
<block wx:for="{{movies}}">
<view class="movie" bindtap="detail" id="{{item.id}}">
<view class="pic">
<image src="{{item.images.medium}}" mode="aspectFit" />
</view>
<view class="movie-info">
<view class="base-info">
<text>{{item.basicInfo}}</text>
</view>
</view>
</view>
<view class="hr"></view>
</block>
</template>
<view class="movie" bindtap="detail" id="{{item.id}}">這段程式碼裡id這個屬性繫結的值{{item.id}}就是某一條電影的id。
所以電影的id一開始就應該存在於對應頁面的wxml程式碼裡,比如存在於home.wxml裡。
上面這段程式碼裡的bindtap=”detail”代表一個點選事件,在頁面上點選view元件後,會啟用對應js檔案裡的detail函式,並跳轉到detail頁面。
//home.js
detail:function(e) {//點選事件e為引數
wx.navigateTo({
url: '../detail/detail',
})
}
function(e)裡的引數e是點選對應元件後返回的事件處理函式的引數,這個引數型別是object,裡面有一個currentTarget的物件,這個物件有個屬性id,這個id表示當前元件的id,用 e.currentTarget.id就可以得到當前元件的id。還記得嗎,元件的id被賦值為{{item.id}},此處的item表示列表渲染時,每一個數組元素的值,這個值就是某部電影物件的詳細資訊,{{item.id}}表示某部電影的id。也就是詳情頁面通過API介面獲得資訊需要的id。
到現在為止,id仍然只在“影院熱映”這個頁面裡,需要這個id的是詳情頁面,那怎麼才能把id傳遞到詳情頁面裡去呢?
有兩種方法:
- 利用快取,在home.js快取id,然後從detail.js處取出。
- 利用頁面跳轉帶去引數
這裡以方法1為例。
//home.js
detail:function(e) {//點選事件e為引數
wx.setStorageSync('id', e.currentTarget.id)
wx.navigateTo({
url: '../detail/detail',
})
}
wx.setStorageSync()之後,id就存到了本地,detail.js從本地取出來使用即可。
loadMovie: function() {
var page = this;
var id = wx.getStorageSync('id');
wx.request({
url: 'https://api.douban.com/v2/movie/subject/'+id,//需要傳遞具體的id才能載入電影;
header: {
'Content-type': 'json'
},
success: function(res){
var subject=res.data;//
subjectUtil.processSubject(subject);
page.setData({movie:subject});
},
complete:function(e) {
wx.hideToast();
}
});```
好了,到現在為止,已經明白了點選元件跳轉到電影詳情這個功能背後的id是如何傳遞的了。
那麼回到最開始,為什麼我在點選home頁面時,detail頁面會出錯呢?因為我同時使用了兩種傳遞id的辦法,而且將detail: function(e){}作為全域性函式寫在app.js供其他頁面引用的時候因為粗心大意出了問題,不過這個問題也讓我對微信MINA框架裡的資料快取有了進一步的理解。要把這個問題講明白還需要一些圖片和程式碼,下一篇文章再總結吧。