0

私は、この素晴らしいフレームワークのコツを学ぼうとしている 5 日間の Yii ファンです。私の問題を読んで助けていただければ幸いです。

ここでは、オンライン マーケットプレイスの特定のマーチャントが Web サービスを通じて販売した製品のリストを取得しています。このようにWebサービスにクエリを実行すると

api.marketplace.com?merchant_id=1234

2 つの主要なデータで構成される JSON で応答を返します。

  1. マーチャント 1234 が販売した商品の数 ( total_products )
  2. 販売された製品のリスト (配列) ( list_product )。この配列の各要素は、それぞれproduct_idproduct_nameの 2 つのフィールドを持つ 1 つの個別の Product オブジェクトを表します。

したがって、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 のままです。

だから私の質問は、一度にProductDataProvider10個の製品のみを取得してCGridViewにロードするように、これをどのように活用するのですか? CGridView は、ページネーションを有効にするために合計 934 個の製品があることを認識している必要があります。ユーザーが CGridView の他のページを参照すると、ProductDataProvider がトリガーされ、表示されているページ番号に対応する次の 10 レコードが取得されます。私の長々とした質問が理解できることを願っています。

4

2 に答える 2

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 リクエストを行うことに注意してください。1 つのリクエストだけで十分であると言う人もいますが、この場合、そのリクエストはすべてのデータ (934 要素) を返します。とても重い。

それだけです。

于 2013-07-01T08:01:22.127 に答える