1. 程式人生 > >從點選事件看微信小程式的資料傳遞

從點選事件看微信小程式的資料傳遞

最近用微信小程式做了一個電影類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傳遞到詳情頁面裡去呢?

有兩種方法:

  1. 利用快取,在home.js快取id,然後從detail.js處取出。
  2. 利用頁面跳轉帶去引數

這裡以方法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框架裡的資料快取有了進一步的理解。要把這個問題講明白還需要一些圖片和程式碼,下一篇文章再總結吧。