TRAJOIN is an Application to Translate symfony documents Jointly.

home > 1.2/cookbook/en > pager.txt

[1] Edit ↑TOP

リストをパジネートする方法


[2] Edit ↑TOP

概要


[3] Edit ↑TOP

symfonyはページャコンポーネントを提供します: sfPropelPagerです。(Criteriaクラスの)クリテリアオブジェクトからの結果のリストを表示のためのページのセットに分割し、ページへのアクセスメソッドと結果オブジェクトを提供することが出来ます。


[4] Edit ↑TOP

sfPropelPagerオブジェクト


[5] Edit ↑TOP

sfPropelPagerクラスはモデルの章で説明されているPropel抽象化レイヤーを使用します。


[6] Edit ↑TOP

この章ではシンプルな例でsfPropelPagerメソッドを使用する方法を説明します: 10×10の記事リストを表示することです。ArticleオブジェクトはgetPublished()getTitle()getOverview()getContent()アクセサメソッドを持ちます。


[7] Edit ↑TOP

クリテリアリクエストのパジネートされていない結果が欲しい場合、次の内容が必要になります:


[8] Edit ↑TOP

class articleActions extends sfActions
{
  public function executeList()
  {
    ...
    $c = new Criteria();
    $c->add(ArticlePeer::PUBLISHED, true);
    $articles = ArticlePeer::doSelect($c);
    $this->articles = $articles;
    ...
  }
}

[9] Edit ↑TOP

$articles変数は、テンプレートからアクセス可能で、リクエストにマッチするArticleオブジェクトの配列を含みます。


[10] Edit ↑TOP

パジネートされたリストを取得するために、微妙に異なるアプローチが必要です; 配列の代わりにsfPropelPagerオブジェクトに結果が収納されなければなりません:


[11] Edit ↑TOP

class articleActions extends sfActions
{
  public function executeList()
  {
    ...
    $c = new Criteria();
    $c->add(ArticlePeer::PUBLISHED, true);
    $pager = new sfPropelPager('Article', 10);
    $pager->setCriteria($c);
    $pager->setPage($this->getRequestParameter('page', 1));
    $pager->init();
    $this->pager = $pager;
    ...
  }
}

[12] Edit ↑TOP

このアクション以降で、クリテリアの定義の後で違いが始まります:


[13] Edit ↑TOP
  • 10×10のArticleオブジェクトをパジネートするために新しいページャを作成します
  • クリテリアからページャへ影響を与える
  • 現在のページをリクエストされたページもしくは最初のものに設定する
  • ページャを初期化する(すなわち、クリテリアに関連したリクエストを実行する)
  • $pager変数経由でページャをテンプレートに渡す

[14] Edit ↑TOP

listSuccess.phpテンプレートはsfPropelPagerオブジェクトをアクセスすることが出来ます。このオブジェクトは現在のページとすべてのページのリストを知っています。ページとページにあるオブジェクトをアクセスするメソッドを持ちます。操作する方法を見てみましょう。


[15] Edit ↑TOP

結果のトータルの数字を表示するために、getNbResults()メソッドを使用して下さい:


[16] Edit ↑TOP

<?php echo $pager->getNbResults() ?> results found.<br />
Displaying results <?php echo $pager->getFirstIndice() ?> to  <?php echo $pager->getLastIndice() ?>.

[17] Edit ↑TOP

リクエストされたページの記事を表示するために、ページでオブジェクトを取得するpagerオブジェクトのgetResults()メソッドを使用して下さい:


[18] Edit ↑TOP

<?php foreach ($pager->getResults() as $article): ?>
  <?php echo link_to($article->getTitle(), 'article/read?id='.$article->getId()) ?>
  <?php echo $article->getOverview() ?>
<?php endforeach ?>

[19] Edit ↑TOP

複数のページをまたがってナビゲートする


[20] Edit ↑TOP

haveToPaginate()メソッドのおかげでページャオブジェクトは結果の数が一つのページ(例では10)が表示される最大数を超えているかを知っています。


[21] Edit ↑TOP

(« < > »)リストの底でナビゲーションリンクを追加するために、getfirstPage()getPreviousPage()getLastPage()などのナビゲーションメソッドを使用して下さい。現在のページはgetPage()によって与えられます。すべてこれらのメソッドは整数を返します: リクエストされたページのランクです。


[22] Edit ↑TOP

特定のページを指定するために、getLinks()メソッドへのコールによって取得されるリンクのコレクションを通してループして下さい:


[23] Edit ↑TOP

<?php if ($pager->haveToPaginate()): ?>
  <?php echo link_to('«', 'article/list?page='.$pager->getFirstPage()) ?>
  <?php echo link_to('<', 'article/list?page='.$pager->getPreviousPage()) ?>
  <?php $links = $pager->getLinks(); foreach ($links as $page): ?>
    <?php echo ($page == $pager->getPage()) ? $page : link_to($page, 'article/list?page='.$page) ?>
    <?php if ($page != $pager->getCurrentMaxLink()): ?> - <?php endif ?>
  <?php endforeach ?>
  <?php echo link_to('>', 'article/list?page='.$pager->getNextPage()) ?>
  <?php echo link_to('»', 'article/list?page='.$pager->getLastPage()) ?>
<?php endif ?>

[24] Edit ↑TOP

これは次のようにレンダーします:


[25] Edit ↑TOP

   « < 1 - 2 - 3 - 4 - 5 > »


[26] Edit ↑TOP

記事が一旦表示されると、パジネートされたリストに戻ることなく前か次の記事にナビゲーションを導くことを可能になり、カーソルが必要になります。


[27] Edit ↑TOP

複数のオブジェクトをまたがってナビゲートする


[28] Edit ↑TOP

リストの範囲内にあるページごとにページをナビゲートすることを簡単ですが、ユーザーはオブジェクトごとにオブジェクトをナビゲートするリストに戻ることは望まないでしょう。sfPropelPagerオブジェクトのcursor属性は現在のオブジェクトのオフセットを保持します。


[29] Edit ↑TOP

このことによってreadSuccess.phpテンプレートにある記事ナビゲーションごとの記事が可能になります。最初に、listSuccess.phpテンプレートのコードを少し修正しましょう:


[30] Edit ↑TOP

<?php $cursor = $pager->getFirstIndice(); foreach ($pager->getResults() as $article): ?>
  <?php echo link_to($article->getTitle(), 'article/read?cursor='.$cursor) ?>
  <?php echo $article->getOverview() ?>
<?php ++$cursor; endforeach ?>

[31] Edit ↑TOP

readアクションはcursorパラメータを取り扱う方法を知る必要があります:


[32] Edit ↑TOP

class articleActions extends sfActions
{
  public function executeRead()
  {
    ...
    if ($this->getRequestParameter('cursor'))
    {
      $article = $pager->getObjectByCursor($this->getRequestParameter('cursor'));
    }
    else if ($this->getRequestParameter('id'))
    {
      $article = ArticlePeer::retrieveByPK($this->getRequestParameter('id'));
    }

    // エラー
    $this->forward404Unless($article);
  }
}

[33] Edit ↑TOP

getObjectByCursor($cursor)メソッドは指定したポジションでカーソルを設定し、まさにそのポジションでオブジェクトを返します。


[34] Edit ↑TOP

setCursor($cursor)メソッドでオブジェクトの取得と結果無しにカーソルを設定することが出来ます。カーソルが一旦設定されると、このポジション(getCurrent())での現在のオブジェクトだけでなく、前のもの(getPrevious())と次のもの(getCurrent())を取得することが出来ます。


[35] Edit ↑TOP

このことはreadアクションは少しの修正で記事ごとの記事のためにテンプレートと必要な情報に移動することが出来ることを意味します。


[36] Edit ↑TOP

class articleActions extends sfActions
{
  public function executeRead()
  {
    ...
    if ($this->getRequestParameter('cursor'))
    {
      $pager->setCursor($this->getRequestParameter('cursor'));
      $previous_article = $pager->getPrevious();
      $article = $pager->getCurrent();
      $next_article = $pager->getNext();
    }
    else if ($this->getRequestParameter('id'))
    {
      $article = ArticlePeer::retrieveByPK($this->getRequestParameter('id'));
    }

    // エラー
    $this->forward404Unless($article);
  }
}

[37] Edit ↑TOP
: getPrevious()getNext()メソッドは前もしくは次のオブジェクトが存在しない場合はnullを返します。


[38] Edit ↑TOP

readSuccess.phpテンプレートは次のように見えます:


[39] Edit ↑TOP

<h1><?php echo $article->getTitle() ?></h1>
<p class="overview"><?php echo $article->getOverview() ?></p>
<div class="content">
  <?php echo $article->getContent() ?>
</div>
< <?php echo link_to_if($previous_article, $previous_article->getTitle(), 'article/read?id='.$previous_article->getId()) ?>
-
> <?php echo link_to_if($next_article, $next_article->getTitle(), 'article/read?id='.$next_article->getId()) ?>

[40] Edit ↑TOP

ソートの順番を変更する


[41] Edit ↑TOP

sfPropelPagerオブジェクトはCriteriaオブジェクトに依存するので、ページャの順序を変更することはページャオブジェクトに割り当てる前に、クリテリアにソートを追加することでシンプルに行われます。


[42] Edit ↑TOP

例えば、ソートカラムの選択をリストナビゲーションインターフェイスに追加することが出来ます:


[43] Edit ↑TOP

class articleActions extends sfActions
{
  public function executeList()
  {
    ...
    $c = new Criteria();
    $c->add(ArticlePeer::PUBLISHED, true);
    if ($this->getRequestParameter('sort'))
    {
      $c->addAscendingOrderByColumn(ArticlePeer::translateFieldName($this->getRequestParameter('sort'), BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME));
    }
    else
    {
      // デフォルトで日付によってソートされます
      $c->addAscendingOrderByColumn(ArticlePeer::UPDATED_AT);
    }
    $pager = new sfPropelPager('Article', 10);
    $pager->setCriteria($c);
    $pager->init();
    $this->pager = $pager;
    ...
  }
}

[44] Edit ↑TOP

listSuccess.phpテンプレートに次のコードを追加します:


[45] Edit ↑TOP

Sort by : <?php echo link_to('Title', 'article/list?sort=title') ?> - <?php echo link_to('Id', 'article/list?sort=Id') ?>

[46] Edit ↑TOP

ページごとの結果数を変更する


[47] Edit ↑TOP

setMaxPerPage($max)メソッドはページャを再処理する必要無しに(init()を再び呼び出す必要がない)ページごとに表示される結果数を変更します。パラメータとして0の値を渡す場合、ページャは一つの単独のページですべての結果を表示します。


[48] Edit ↑TOP

class articleActions extends sfActions
{
  public function executeList()
  {
    ...
    $c = new Criteria();
    $c->add(ArticlePeer::PUBLISHED, true);
    $pager = new sfPropelPager('Article', 10);
    $pager->setCriteria($c);
    if ($this->getRequestParameter('maxperpage'))
    {
      $pager->setMaxPerPage($this->getRequestParameter('maxperpage'));
    }
    $pager->init();
    $this->pager = $pager;
    ...
  }
}

[49] Edit ↑TOP

listSuccess.phpテンプレートに次のコードを追加します:


[50] Edit ↑TOP

Display : <?php echo link_to('10', 'article/list?maxperpage=10') ?> - <?php echo link_to('20', 'article/list?maxperpage=20') ?> results per page

[51] Edit ↑TOP

selectメソッドを変更する


[52] Edit ↑TOP

sfPropelPagerに依存するアクションのパフォーマンスを最適化する必要がある場合、シンプルなdoSelect()の代わりにdoSelectJoinXXX()を使用するページャを強制したいでしょう。sfPropelPagerオブジェクトのsetPeerMethod()メソッドによって簡単に獲得出来ます:


[53] Edit ↑TOP

$pager->setPeerMethod('doSelectJoinUser');

[54] Edit ↑TOP

ページを表示するときにページャは実際にdoSelect()クエリを処理することに留意して下さい。最初のクエリ($pager->init()によって引き起こされます)はdoCountをするだけですが、次のコードを呼び出すことでこのメソッドをカスタマイズすることも出来ます:


[55] Edit ↑TOP

$pager->setPeerCountMethod('doCountJoinUser');

[56] Edit ↑TOP

ページャで追加情報を保存する


[57] Edit ↑TOP

ページャオブジェクトである種のコンテキストを保存する必要があるかも知れません。sfPropelPagerクラスが通常の方法でパラメータを処理できる理由はそういうわけです:


[58] Edit ↑TOP

$pager->setParameter('foo', 'bar');

if ($pager->hasParameter('foo'))
{
  $pager->getParameter('foo');
  $pager->getParameterHolder()->removeParameter('foo');
}

$pager->getParameterHolder()->clearParameters();

[59] Edit ↑TOP

これらのパラメータはけっしてページャによって直接使用されません。


[60] Edit ↑TOP

To learn more about custom parameters, refer to the Chapter 2.


Comments

Menu

Documentation



Latest Histories

To learn more about custo ...
brtRiver(2009-01-05 04:00:22)
These parameters are neve ...
brtRiver(2009-01-05 04:00:09)
[php] $pager-> ...
brtRiver(2009-01-05 04:00:02)
You may need sometimes to ...
brtRiver(2009-01-05 03:59:46)
Storing additional inform ...
brtRiver(2009-01-05 03:59:36)
[php] $pager-> ...
brtRiver(2009-01-05 03:59:27)
Note that the pager actua ...
brtRiver(2009-01-05 03:59:16)
[php] $pager-> ...
brtRiver(2009-01-05 03:59:03)
If you need to optimize t ...
brtRiver(2009-01-05 03:58:53)
Changing the select metho ...
brtRiver(2009-01-05 03:58:42)
[php] Display : & ...
brtRiver(2009-01-05 03:58:30)
So you can add the follow ...
brtRiver(2009-01-05 03:58:19)
[php] class artic ...
brtRiver(2009-01-05 03:58:11)
The `setMaxPerPage($max)` ...
brtRiver(2009-01-05 03:57:57)
Changing the number of re ...
brtRiver(2009-01-05 03:57:49)
[php] Sort by : & ...
brtRiver(2009-01-05 03:57:40)
Add the following to the ...
brtRiver(2009-01-05 03:57:28)
[php] class artic ...
brtRiver(2009-01-05 03:57:20)
For instance, you can add ...
brtRiver(2009-01-05 03:57:05)
As the `sfPropelPager` ob ...
brtRiver(2009-01-05 03:56:57)

Untranslated