我是一个为期5天的Yii粉丝试图学习这个伟大框架的绳索。如果你能忍受我阅读我的问题并帮助我,我将非常感激。
所以这里,我正在通过其网络服务检索由在线市场的特定商家销售的产品列表。当我像这样查询Web服务时
api.marketplace.com?merchant_id=1234
我将在JSON中找回包含两个主要数据
的响应因此,如果 total_products = 934 ,则数组中将有934个元素。 当我把它放在代码中时,我的派生DataProvider看起来像这样
class ProductDataProvider extends CDataProvider /* or should I extend other better class? */ {
public function __construct($config = array()) {
foreach($config as $key=>$value)
$this->$key=$value;
}
protected function fetchData() {
$request = "api.marketplace.com?merchant_id=1234";
$response = retrieveProductsAndProcessJSONResponseIntoAppropriateDataStructure($request);
$this->setTotalItemCount($response->total_products);
if(($pagination=$this->getPagination())!==false)
$pagination->setItemCount($this->getTotalItemCount());
return $response->list_products;
}
protected function calculateTotalItemCount() {
return $this->getTotalItemCount();
}
}
我的模特
class Product extends CModel {
public $product_id;
public $product_name;
public function display() {
return new ProductDataProvider(array(
'pagination'=>array(
'pageSize'=>10,
));
}
}
和我的观点
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'product-grid',
'dataProvider'=>$model->display(),
'columns'=>array(
'product_id',
'product_name',
),
));
这适用于分页和所有这些。然而,检索所有934产品需要花费太长时间。我们可以对Web服务执行此操作。
api.marketplace.com?merchant_id=1234&page_size=10&page_no=1
这只会检索前10条记录。我们可以使用查询字符串变量 page_no 来检索10个组中的后续产品页面。从Web服务返回的 total_products 仍然是934。
所以我的问题是,我如何将其付诸实践,以便ProductDataProvider
在任何时候只检索10个产品并将其加载到CGridView中? CGridView必须知道总共有934种产品可以实现分页。用户浏览到CGridView的其他页面将触发ProductDataProvider以检索与正在查看的页码对应的下10个记录。我希望我长篇大论的问题是可以理解的。
答案 0 :(得分:0)
我认为您需要创建自己的自定义数据提供程序。请参阅CDataProvider
的班级参考Yii中有三个已实施的数据提供者。 CActiveDataProvider,CArrayDataProvider和CSqlDataProvider。您可以将它们用作自定义数据提供程序的模型。
答案 1 :(得分:0)
我有同样的问题。所以,我想:
首先,您应该实现CDataProvider
中的所有3个抽象方法。在您的班级fetchKeys()
未实施。
其次,分页逻辑应放在fetchData
中。例如:
protected function fetchData() {
$request = "api.marketplace.com?merchant_id=1234";
// page size
$request .= "&page_size=".$this->pagination->pageSize;
// current page
$request .= "&page_no=".$this->pagination->currentPage;
$response = retrieveProductsAndProcessJSONResponseIntoAppropriateDataStructure($request);
return $response->list_products;
}
要使用新的自定义数据提供程序,请按以下方式编写smth:
$dataProvider = new CustomDataProvider();
$pages = new CPagination($dataProvider->getTotalItemCount());
$pages->pageSize = 40; // page size
$dataProvider->pagination = $pages;
数据提供商使用calculateTotalItemCount()
获取项目总数。所以,此外,你应该写一些逻辑来提供总项数。猜猜,您应该在API中使用另一种方法来实现此目的。请记住,如果您使用分页,您的数据提供者将执行2个api请求:第一个用于总项目计数,第二个用于当前页面项目。有人可以说只有一个请求就足够了,但在这种情况下,该请求将返回所有数据(934个元素)。太沉重了。
这就是你所需要的一切。