CakePHP:home.ctp中元素的分页

时间:2012-05-23 09:43:07

标签: php pagination cakephp-2.1

我正在使用CakePHP使用MySQL后端为PowerDNS创建前端UI。在应用程序的首页我想要一些小部件('快速添加记录','快速添加域'等)。我想要的一个小部件是现有域的分页列表。

DomainsController.php中的索引函数如下所示:

public $paginate = array(
  'fields'     => array('id', 'name'),
  'limit'      => 25,
  'order'      => array( 'name' => 'asc' ),
  'conditions' => array( "NOT" => array( "name LIKE" => "%.arpa" ) )
);

public function index() {
  $domains = $this->paginate();
  if ( $this->request->is('requested')) {
    return $domains;
  } else {
    $this->set('domains', $domains);
  }
}

我创建了一个如下所示的元素:

<?php $domains = $this->requestAction('Domains/index'); ?>

<ol>
  <?php foreach( $domains as $domain) :?>
    <li>echo $domains['domain']['name']</li>
  <?php endforeach; ?>
</ol>

<?php echo $paginator->numbers(); ?>

当我访问首页时,我收到一个'Undefinied variable:paginator'错误。我尝试过使用$ this-&gt; Paginator-&gt; numbers()而只是给了我'Undefined属性:View :: $ Paginator'。将'Paginator'帮助器添加到PagesController.php也无济于事 - $ this-&gt; Paginator变得可用,但我得到'Undefined index:pageCount'。

是否有可能从home.ctp上的元素进行这种分页,或者我将不得不做一些自定义JavaScript的东西?

修改

现在我到了某个地方:我将DomainsController索引功能更改为:

public function index() {
 $domains = $this->paginate();
 $paginator = $this->params;
 if ( $this->request->is('requested')) {
  return compact( 'domains', 'paginator' );
 } else {
  $this->set('domains', $domains);
 }
}

并将以下内容添加到domainList.ctp元素:

<?php 
$result = $this->requestAction('Domains/index');
$domains = $result['domains'];
$this->Paginator->request = $result['paginator'];
?>

<ol>
  <?php foreach( $domains as $domain) :?>
    <li>echo $domains['domain']['name']</li>
  <?php endforeach; ?>
</ol>

<?php echo $paginator->numbers(); ?>

$ this-&gt; Paginator现在正常工作,我可以像往常一样访问它的所有方法和属性等等。我现在的问题是,如果我点击,例如,'2',浏览器导航到/ pages / home / page:2但域列表仍显示第1页。只需要弄清楚如何传递'page:2'对元素。和AJAX-ify整个事情,所以我不需要刷新整个页面。

2 个答案:

答案 0 :(得分:0)

首先,不要这样做:

$ domains = $ this-&gt; requestAction('Domains / index'); 这是昂贵的,而不是很好的做法,我不知道为什么你需要从你的例子中做到这一点。

其次,像这样调用您的分页:

$ domains = $ this-&gt; Paginate('Domain');

答案 1 :(得分:0)

好的,我解决了这个问题,虽然我的解决方案可能不是很优雅。

DomainsController.php有一个listDomains()函数,如下所示:

public function listDomains() {
 $domains = $this->paginate(); 
 $paginator = $this->params;
 if ( $this->request->is('ajax') ) {
  $this->set( 'domains', $domains );
 }
 if ( $this->request->is('requested')) {
  return array( 'domains' => $domains, 'paginator' => $paginator, 'paging' => $this->params['paging'] );
 } else {
  $this->set( 'domains', $domains );
 }
}

home.ctp引用一个名为domainList.ctp的元素。 domainList.ctp,下面,反过来使用requestAction() - 我知道,我知道 - 调用上面的domainList()函数。请求请求请求,包含$ domains和$ paginator值的数组将被发送回元素。

domainList.ctp包含以下代码:

<?php
$result = $this->requestAction('Domains/listDomains', array('updateId' => 'domainList') );
$domains = $result['domains'];
$paginator = $result['paginator'];
$this->Paginator->request = $paginator;

$this->Paginator->options(array(
 'update' => '#domainList',
 'evalScripts' => true,
 'url' => array('controller' => 'Domains', 'action' => 'listDomains', 'updateId' => 'domainList' ),
));

?>

基本上我在这里做的是用最初发送到DomainController的domainList()函数的params手动重新填充$ this-&gt; Paginator-&gt;请求。这让我可以正确访问各种paginator函数,比如numbers(),prev()和next()。这有点乱,但你猜怎么着?它变得有点麻烦。

当您点击这些分页器功能创建的链接时,会执行'if($ this-&gt; request-&gt; is('ajax'))'段,并更新页面上的div对象View / Domains / domainList.ctp的内容,而不是View / Elements / domainList.ctp。 View / Domains / domainList.ctp的内容或多或少与相应的元素相同,并且两者必须是或多或少同步的kep。不同之处在于我们不需要手动填充$ this-&gt; Paginator:

<?php
$this->Paginator->options(array(
 'update' => '#domainList',
 'evalScripts' => true,
 'url' => array('controller' => 'Domains', 'action' => 'listDomains', 'updateId' => 'domainList' ),
));

?>

就像我说的那样,它既凌乱又不雅,但它对我有用。我很高兴知道是否有人这样做的方式较少。