0

我是一个 5 天的 Yii 粉丝,试图了解这个伟大框架的原理。如果您能忍受我阅读我的问题并帮助我,我将不胜感激。

因此,我正在检索在线市场的特定商家通过其网络服务销售的产品列表。当我像这样查询网络服务时

api.marketplace.com?merchant_id=1234

我将以 JSON 格式返回响应,其中包含两个主要数据

  1. Merchant 1234 销售的产品数量(total_products
  2. 已售产品的列表(数组)(list_product)。此数组中的每个元素代表一个不同的 Product 对象,该对象具有两个字段:分别是product_idproduct_name

因此,如果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 条记录。我希望我冗长的问题是可以理解的。

4

2 回答 2

0

我认为您需要创建自己的自定义数据提供程序。请参阅CDataProvider的类参考

Yii 中实现了三个数据提供者。CActiveDataProvider、CArrayDataProvider 和 CSqlDataProvider。您可以将它们用作自定义数据提供者的模型。

于 2013-07-01T00:38:59.947 回答
0

我遇到过同样的问题。所以我认为:

首先,您应该实现所有 3 个抽象方法CDataProvider。在您的班级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;
}

要使用新的自定义数据提供程序,请像这样编写:

$dataProvider = new CustomDataProvider();
$pages = new CPagination($dataProvider->getTotalItemCount());
$pages->pageSize = 40; // page size
$dataProvider->pagination = $pages;

数据提供者使用 获取项目总数calculateTotalItemCount()。因此,此外,您应该在那里编写一些逻辑来提供总项目数。猜猜,您应该为此目的在您的 API 中利用另一种方法。请记住,如果您使用分页,您的数据提供者将执行 2 个 api 请求:第一个请求总项目数,第二个请求当前页面项目。有人可以说只有一个请求就足够了,但在这种情况下,该请求将返回所有数据(934 个元素)。这么重。

这就是你所需要的。

于 2013-07-01T08:01:22.127 回答