0

我正在使用 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(); ?>

当我访问首页时,我收到“未定义变量:分页器”错误。我尝试使用 $this->Paginator->numbers() 代替,但这只是给了我“未定义的属性:View::$Paginator”。将“Paginator”助手添加到 PagesController.php 也无济于事 - $this->Paginator 可用,但我得到“未定义索引: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->Paginator 现在工作正常,我可以正常访问它的所有方法和属性等等。我现在的问题是,如果我点击“2”,浏览器会导航到 /pages/home/page:2 但域列表仍然显示第 1 页。只需要弄清楚如何传递“page:2”到元素。并且 AJAX-ify 整个事情,这样我就不需要刷新整个页面。

4

2 回答 2

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() 函数。Bequest 请求被请求,包含 $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' ),
));

?>

本质上,我在这里所做的是手动重新填充 $this->Paginator->request 与最初发送到 DomainController 的 domainList() 函数的参数。这让我可以正确访问各种分页器功能,例如 numbers()、prev() 和 next()。这有点混乱,但你猜怎么着?它变得有点混乱。

当您单击由这些分页器函数创建的链接时,会执行“if ($this->request->is('ajax'))”段,并且页面上的 div 对象会使用 View/Domains 的内容进行更新/domainList.ctp 而不是 View/Elements/domainList.ctp。View/Domains/domainList.ctp 的内容与相应的元素或多或少相同,两者必须或多或少保持同步。不同的是我们不需要手动填充 $this->Paginator:

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

?>

就像我说的那样,它既凌乱又不优雅,但它对我有用。我很高兴知道是否有人有不那么笨拙的方法来做到这一点。

于 2012-06-01T17:54:19.603 回答
0

首先,不要这样做:

$domains = $this->requestAction('Domains/index'); 这是昂贵的,不是好的做法,我不确定你为什么需要从你的例子中这样做。

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

$domains = $this->Paginate('Domain');

于 2012-05-23T10:28:19.140 回答