微信小程式 / 第十三篇 相簿內容瀏覽

阿北哥ya發表於2017-11-16

在上幾篇中我們成功建立了相簿、上傳圖片、上傳視訊,本節實戰瀏覽一個相簿內容,看看都傳了啥!

在本篇你講學到的知識有

  • image和video元件
  • yii2中restfule的prepareDataProvider方法的使用

當然這一切還是從服務端開始

伺服器

從邏輯上說就是點選一個相簿後將屬於這個相簿的所有photo記錄都拿出來,這應該是yii2中restful的index方法,但是有一個問題就是呼叫index方法的時候需要傳遞一個引數過去,album_id!

而預設情況下使用index方法的時候是無法傳遞引數的,好在yii2已經為我們提供了一個函式用來處理這方面需求 --- prepareDataProvider

我們首先過載下PhotoItemController的index方法,如下程式碼

public function actions() {
    $actions = parent::actions();
    unset($actions['create']);
    $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider'];
    return $actions;
}複製程式碼

yii2的restful針對於index方法內建了一個prepareDataProvider方法,用來準備資料集記錄,我們通過對其重寫編寫來設定帶有album_id的查詢條件。

於是我重寫了prepareDataProvider方法

public function prepareDataProvider(){
    $params = Yii::$app->request->queryParams;

    $query = Photo::find()->where(['album_id'=>$params['album_id']]);
    $provider = new ActiveDataProvider([
        'query'=>$query
    ]);

    return $provider;
}複製程式碼

通過Yii::$app->request->queryParams獲取本次請求的get引數,將得到的$params['album_id']傳遞給ActiveDataProvider獲取具體相簿的photo記錄。

看看效果圖

alt
alt

更多關於yii2的restful方法可以在這裡學習 nai8.me/course-book…

小程式

當點選某個相簿的時候我希望每個photo記錄按照上傳時間降序排序,並且在photo記錄的列表頁也會呈現出圖片和視訊。

好東西要一口一口吃,我先實現photo列表而不考慮圖片和視訊問題。

為此我在album資料夾內新建了一個view的page,它由album/list點選而來。獲取photo記錄的思路和之前講過的獲取相簿列表一樣。

  • 首先在data裡設定一個album_id並在頁面 onLoad 的時候由相簿列表頁傳遞過來id對其賦值。
  • 根據album_id從伺服器分頁形式獲取photo記錄集合並渲染給檢視。

我想你對上面的實現已經胸有成竹了吧,我將從後臺獲取資料的程式碼寫一下(更詳細的程式碼請從github上拉下來)

loadList: function () {
    if (hadLastPage != false) {
        wx.showToast({
            title: '到底了',
        })
        return;
    }

    var that = this;
    wx.request({
        method: 'GET',
        url: 'http://xgh.local.com/xcx/photo-items',
        data: {
            fields: 'id,name,description',
            album_id:that.data.album_id,
            page: page
        },
        header: {
            'content-type': 'application/json'
        },
        success: function (res) {
            var listData = that.data.photos;
            for (var i = 0; i < res.data.length; i++) {
                listData.push(res.data[i]);
            }

            if (res.header["X-Pagination-Page-Count"] == res.header["X-Pagination-Current-Page"]) {
                hadLastPage = res.header["X-Pagination-Current-Page"];
            } else {
                page++;
            }

            that.setData({
                photos: listData
            });
        },
    })
}複製程式碼

現在相簿的photo記錄已經存到了view頁面的photos中,接下來放到wxml渲染出來,看下方程式碼

<view class="photos">
    <block wx:for="{{photos}}" wx:key="id" wx:for-index="idx" wx:for-item="photo">
        <view class="photo">
            <view class="desc">{{photo.description}}</view>
        </view>
    </block>
</view>複製程式碼

看看效果圖

alt
alt

優化photo列表

這樣是不夠的,我們還要進一步進行優化,首先優化圖片類photo,我希望每個photo介紹下面直接是2*2形式的圖片矩陣。

也就是說我在獲取每個photo的同時還要順便獲取其下的photo_item。

但是photo資料表是沒有photo_item欄位的,幸好我們的yii2有那個extraFields方法,開始部署吧,首先我在小程式從後臺獲取photo記錄的請求data中重新設定如下

data: {
    fields: 'id,name,description,type',
    album_id:that.data.album_id,
    expand: 'photos',
    page: page
},複製程式碼

然後針對photo模型增加如下方法

public function extraFields() {

    return [
        'photos'
    ];
}

public function getPhotos(){
    $data = PhotoItem::find()->where(['photo_id'=>$this->id])->all();

    $return = [];
    foreach($data as $item){
        $return[] = [
            'path'=>Yii::$app->request->getHostInfo()."/static/".$item->path
        ];
    }

    return $return;
}複製程式碼

現在再看看相簿詳情頁面photo記錄的伺服器響應資料

alt
alt

達到目的,現在開始渲染檢視,有個特別情況需要說下,當photo記錄的photos照片返回一個的時候,就不要2*2了,直接顯示即可。

因此我對相簿詳情的檢視進行了如下優化。

<view class="photos">
    <block wx:for="{{photos}}" wx:key="id" wx:for-index="idx" wx:for-item="photo">
        <view class="photo">
            <view class="desc">{{photo.description}}</view>
            <view class="items">
                <block wx:for="{{photo.photos}}" wx:if="{{photo.photos.length==1}}" wx:key="id" wx:for-index="pidx" wx:for-item="photoItem">
                    <image src="{{photoItem.path}}" style="width:10em;height:10em;"></image>
                </block>

                <block wx:for="{{photo.photos}}" wx:if="{{photo.photos.length>1}}" wx:key="id" wx:for-index="pidx" wx:for-item="photoItem">
                    <image src="{{photoItem.path}}" style="width:5em;height:5em;display:inline-block;"></image>
                </block>
            </view>
        </view>
    </block>
</view>複製程式碼

看看效果

alt
alt

我們的目的初步達到了。

遺留的問題

聰明的你一定發現了一些問題,最明顯的就是圖片尺寸問題,應該等比例且真實長寬要適配裝置,另外最好顯示壓縮圖。

這些的確是真實存在的問題,別急,下節將為你解決。

本文原創於 北哥兄弟連,版權所有,轉載請聯絡我微信abei-pg

相關文章