摘要:再看看另一個方法,的提供的數(shù)據(jù)統(tǒng)計總條數(shù)的方法是的,默認計算分頁總數(shù)是根據(jù)數(shù)組計算的,而的數(shù)據(jù)就是我們查詢賦值給提供器的。統(tǒng)計總數(shù)預處理函數(shù)直接獲取通過函數(shù)獲取傳遞給數(shù)據(jù)提供器的數(shù)據(jù)總和。
首先看看ArrayDataProvider官方的doc:
ArrayDataProvider implements a data provider based on a data array.
ArrayDataProvider實現(xiàn)了一個基于數(shù)據(jù)數(shù)組的數(shù)據(jù)提供器。The [[allModels]] property contains all data models that may be sorted and/or paginated.
[[allModels]]包含了需要排序和(或)分頁的所有數(shù)據(jù)模型。ArrayDataProvider will provide the data after sorting and/or pagination.
ArrayDataProvider提供排序和(或)分頁后的數(shù)據(jù)。You may configure the [[sort]] and [[pagination]] properties to
customize the sorting and pagination behaviors.
你可以配置[[sort]]和[[pagination]]屬性自定義排序和分頁行為。Elements in the [[allModels]] array may be either objects (e.g. model objects) or associative arrays (e.g. query results of DAO).
[[allModels]]數(shù)組中的元素也許是對象(如,model對象)也許是關聯(lián)數(shù)組(如,PDO的查詢結果)。Make sure to set the [[key]] property to the name of the field that uniquely identifies a data record or false if you do not have such a field.
確保設置的[[key]]屬性是唯一標識一條記錄的字段的名字,如果沒有這樣的字段,則設為false。Compared to [[ActiveDataProvider]], ArrayDataProvider could be less efficient because it needs to have [[allModels]] ready.
與[[ActiveDataProvider]]比較,ArrayDataProvider可能效率較低,因為它需要準備[[allModels]]。ArrayDataProvider may be used in the following way:
ArrayDataProvider可以按照下面的方式使用:$query = new Query; $provider = new ArrayDataProvider([ "allModels" => $query->from("post")->all(), "sort" => [ "attributes" => ["id", "username", "email"], ], "pagination" => [ "pageSize" => 10, ], ]); // get the posts in the current page $posts = $provider->getModels();Note: if you want to use the sorting feature, you must configure the [[sort]] property
so that the provider knows which columns can be sorted.
注意:你給你想使用排序功能,你必須配置[[sort]]屬性。@author Qiang Xue
@since 2.0
從上面的指南可以看出,使用ArrayDataProvider需要準備好[[allModels]]數(shù)據(jù),才開始渲染視圖,并實現(xiàn)分頁。
ArrayDataProvider是先把數(shù)據(jù)拉渠道內存中,然后再根據(jù)已有數(shù)據(jù)進行分頁,這一點感覺像JQuery的DataTables插件,但是DataTables插件支持異步獲取數(shù)據(jù),也就是說可以根據(jù)配置可以分頁從數(shù)據(jù)庫中獲取數(shù)據(jù),顯然,yii2自帶的ArrayDataProvider明顯不提供此功能。
先看看,yii2的ArrayDataProvider提供預處理models的方法,該方法處理排序和分頁:
/** * @inheritdoc */ protected function prepareModels() { if (($models = $this->allModels) === null) { return []; } if (($sort = $this->getSort()) !== false) { $models = $this->sortModels($models, $sort); } if (($pagination = $this->getPagination()) !== false) { $pagination->totalCount = $this->getTotalCount(); if ($pagination->getPageSize() > 0) { $models = array_slice($models, $pagination->getOffset(), $pagination->getLimit()); } } return $models; }
對于分頁代碼,如過設置了pagination對象,也就是設置了分頁,則統(tǒng)計數(shù)據(jù)總條數(shù),然后根據(jù)每頁的大小分片。
if (($pagination = $this->getPagination()) !== false) {
$pagination->totalCount = $this->getTotalCount(); if ($pagination->getPageSize() > 0) { $models = array_slice($models, $pagination->getOffset(), $pagination->getLimit()); }}
再看看另一個方法,yii2的ArrayDataProvider提供的數(shù)據(jù)統(tǒng)計總條數(shù)的方法:
/** * @inheritdoc */ protected function prepareTotalCount() { return count($this->allModels); }
是的,ArrayDataProvider默認計算分頁總數(shù)是根據(jù)allModels數(shù)組計算的,而allModels的數(shù)據(jù)就是我們查詢賦值給提供器的。
這里面有兩個很重要的方法必須看看:
public function getTotalCount() { if ($this->getPagination() === false) { return $this->getCount(); } elseif ($this->_totalCount === null) { $this->_totalCount = $this->prepareTotalCount(); } return $this->_totalCount; }
該方法就是統(tǒng)計數(shù)據(jù)總數(shù)的,相應的應該有一個設置數(shù)據(jù)總數(shù)的:
public function setTotalCount($value) { $this->_totalCount = $value; }
而在ArrayDataProvider及其分類中,并沒有一個public的totalCount屬性,因此yii在處理的時候,將totalCount通過魔法函數(shù)進行設置,因為yii2中所有的類都是Object的子類,關于魔法函數(shù),這一塊內容參考深入理解yii2.0,在此感謝作者帶我們走的這么深。
因此,不管你分頁不分頁,ArrayDataProvider并不是服務器端分頁的,而是將已有數(shù)據(jù)分頁處理的。
這種情況,如果數(shù)據(jù)量很大的時候,一點也不好,線上服務動輒上百萬的數(shù)據(jù),一下子拿出來分頁,服務器吃不消,你也耗不起這個等待時間。
下面,我們需要重寫這兩個方法:
models預處理方法
取消對已有數(shù)據(jù)的分片處理,統(tǒng)計數(shù)據(jù)總數(shù)根據(jù)我們的方式統(tǒng)計,比如數(shù)據(jù)庫中的總條數(shù)。
/* * @inheritdoc */ protected function prepareModels() { if (($models = $this->allModels) === null) { return []; } if (($sort = $this->getSort()) !== false) { $models = $this->sortModels($models, $sort); } if (($pagination = $this->getPagination()) !== false) { $pagination->totalCount = $this->getTotalCount(); } return $models; }
統(tǒng)計總數(shù)預處理函數(shù)
直接獲取通過getTotalCount()函數(shù)獲取傳遞給數(shù)據(jù)提供器的數(shù)據(jù)總和。
/* * @inheritdoc */ protected function prepareTotalCount() { return $this->getTotalCount(); }
下面給出重寫后的完整ArrayDataProvider:
allModels) === null) { return []; } if (($sort = $this->getSort()) !== false) { $models = $this->sortModels($models, $sort); } if (($pagination = $this->getPagination()) !== false) { $pagination->totalCount = $this->getTotalCount(); } return $models; } /* * @inheritdoc */ protected function prepareTotalCount() { return $this->getTotalCount(); } }
最后,來一個實際使用案例:
// TODO 業(yè)務邏輯 $data = ... // 數(shù)據(jù)數(shù)組或對象 $count = ... // 數(shù)據(jù)總條數(shù),并不是count($data)的值,是數(shù)據(jù)庫中符合條件的所有數(shù)據(jù)總數(shù) $dataProvider = new ackendextensionsArrayDataProvider([ "allModels" => $data, "totalCount" => isset($count) ? $count : 0, "key" => "ltime", "sort" => [ "attributes" => [ "gmv", "ltime", "uv" ], "defaultOrder" => [ "gmv" => SORT_DESC, "ltime" => SORT_DESC, "uv" => SORT_DESC, ], ], "pagination" => [ "pageSize" => 15, ], ]); // 傳遞到test視圖渲染 return $this->render("test", ["model" => $model, "dataProvider" => $dataProvider]);
在視圖層接收該數(shù)據(jù)提供器,傳遞給一個數(shù)據(jù)渲染插件,比如GridView:
echo GridView::widget([ "dataProvider" => $dataProvider, "columns" => [ ["class" => "yiigridSerialColumn"], [ "class" => "yiigridDataColumn", "value" => function ($data) { if (isset($data["ltime"]) && !empty($data["ltime"])) { return date("Y-m-d", $data["ltime"]); } }, "label" => "日期", "format" => "raw", ], "moneyPerUvOrder:raw:訂單UV單價", "moneyPerUvPurchase:raw:銷售UV單價" ] ]);
到此結束,如果幫到你,請點擊收藏!
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/21705.html
摘要:是實現(xiàn)網(wǎng)格視圖的小部件,一般用于報表視圖的展示。就是連續(xù)的列,主要用于網(wǎng)格的行號,屬于自增式的列。指定處理的類,必須。 Yii2 GridView是實現(xiàn)yii網(wǎng)格視圖的小部件,一般用于報表視圖的展示。今天,結合DataProvider(ArrayDataProvider以及SqlDataProvider)說一下GridView中的幾個Columns(SerialColumn,DataC...
摘要:大家知道我最近在給阿北的知識分享微信小程序改版,使用的是中的功能,接下來把遇到的一些問題及小技巧分享一下。小結以上就是目前為止在使用的開發(fā)小程序時候使用的一些知識和技巧,希望對你有用,以后如果有再分享哈。 大家知道我最近在給阿北的知識分享微信小程序改版,使用的是yii2中的restful功能,接下來把遇到的一些問題及小技巧分享一下。 先安利一下小程序碼 鏈接 開始分享。 URL要重寫 ...
摘要:運行來安裝指定的擴展。這更便于用戶辨別是否是的擴展。當用戶運行安裝一個擴展時,文件會被自動更新使之包含新擴展的信息。上述代碼表明該擴展依賴于包。例如,上述的條目聲明將對應于別名。為達到這個目的,你應當在公開發(fā)布前做測試。 簡述 擴展是專門設計的在 Yii 應用中隨時可拿來使用的, 并可重發(fā)布的軟件包。 基礎 例如, yiisoft/yii2-debug 擴展在你的應用的每個頁面底部添加...
摘要:注拍照功能在某些機型上還有閃退現(xiàn)象,希望微信官方可以盡快完善。這涉及到函數(shù),這是微信小程序內置的,用來上傳一個文件,有幾個點要說下綠色框要上傳文件資源的路徑,也就是我們相冊里選擇的圖片路徑。 我們喜歡小程序的原因之一就是它提供了更多和手機系統(tǒng)交互的接口,比如今天要說的這個從相冊選擇 / 拍照功能。注:拍照功能在某些機型上還有閃退現(xiàn)象,希望微信官方可以盡快完善。 在上一篇中我們搞定了相冊...
摘要:不通過日志獲取執(zhí)行的原生語句和打印變量數(shù)據(jù)打印變量數(shù)據(jù)可以這樣寫引用命名空間使用使用第二個參數(shù)是數(shù)組的深度第三個參數(shù)是是否顯示代碼高亮默認不顯示從數(shù)據(jù)庫二維數(shù)組中返回一維數(shù)組并配合驗證規(guī)則實現(xiàn)分類數(shù)據(jù)過濾。 1、不通過日志獲取AR執(zhí)行的原生SQL語句和打印變量數(shù)據(jù) $query = User::find() ->select([username])->where([id=>[1,2,3...
閱讀 2561·2023-04-25 19:24
閱讀 1787·2021-11-11 16:54
閱讀 2892·2021-11-08 13:19
閱讀 3617·2021-10-25 09:45
閱讀 2629·2021-09-13 10:24
閱讀 3394·2021-09-07 10:15
閱讀 4194·2021-09-07 10:14
閱讀 3023·2019-08-30 15:56