2017-05-31 55 views
0

我一直在寻找这个,但一直在寻找任何例子很难。我已将分页添加到我的应用程序,但我希望将其作为Ajax/Async功能,因此整个页面不会重新加载。有没有人有这方面的最佳实践的任何示例/教程?这里是我的代码已经有:CakePHP 3创建Ajax分页/排序

控制器:

public $acronym_paginate = [ 
     'limit' => 25, 
     'fields' => ['id','abbreviation', 'full_text'], 
     'order' => [ 
      'Acronyms.abbreviation' => 'asc' 
     ] 
    ]; 
    public function initialize() { 
     parent::initialize();   
     $this->loadComponent('RequestHandler'); 
     $this->loadComponent("Flash"); 
    } 
    public function index() { 
     $this->loadModel('Acronyms');  
     $acronyms = $this->Acronyms->find('All')->where();  
     $this->set([ 
      'acronyms' => $this->paginate($acronyms), 
      '_serialize' => ['acronyms'] 
     ]);  
    } 

} 

查看:

<table class = "acronymTable" id = "acronymTable" name = "acronymTable" > 
    <thead>   
     <tr> 
      <td style="display:none;"> 
       ID 
      </td> 
      <td width = "10%" style="border:1px solid black; font-weight: bold; padding:10px;"> 
       Acronym 
      </td> 
      <td width = "60%" style = "border:1px solid black; font-weight: bold; padding:10px;"> 
       Definition 
      </td>     
     </tr> 
    </thead> 
    <tbody> 
     <?php foreach ($acronyms as $acronym): ?> 
      <tr id = "<?= $acronym->id ?>" name = "<?= $acronym->id ?>"> 
       <td style="display:none;"><?= $acronym->id ?></td> 
       <td style="padding-left:10px;" id="acronymName-<?= $acronym->id ?>" name="acronymName-<?= $acronym->id ?>" ><?= $acronym->abbreviation ?></td> 
       <td style="padding-left:10px;" id="acronymDef-<?= $acronym->id ?>" name="acronymDef-<?= $acronym->id ?>"><?= $acronym->full_text ?></td>          

      </tr> 
     <?php endforeach; ?>    

    </tbody> 
    <tfoot> 
     <tr> 
      <td colspan="5" style="text-align: center;"> 
       <div class="pagination pagination-large"> 
        <ul class="pagination"> 
         <?php 
          echo $this->Paginator->prev(__('prev'), array('tag' => 'li'), null, array('tag' => 'li','class' => 'disabled','disabledTag' => 'a')); 
          echo $this->Paginator->numbers(array('separator' => '','currentTag' => 'a', 'currentClass' => 'active','tag' => 'li','first' => 1)); 
          echo $this->Paginator->next(__('next'), array('tag' => 'li','currentClass' => 'disabled'), null, array('tag' => 'li','class' => 'disabled','disabledTag' => 'a')); 
         ?> 
        </ul> 
       </div>    

      </td> 
     </tr> 
    </tfoot> 
</table> 

如果没有 “最佳实践” 对于这一点,我想我最大的问题将是如何保持分页按钮,但让他们通过jQuery Ajax调用提交请求。

感谢您的帮助

+0

我在cake3应用做到了这一点,但我没有一个教程或像这样的东西。我可以稍微描述一下。我已经为paginator链接添加了一个click事件,并使用基于生成的href链接进行ajax请求。然后我用我从ajax-request获得的html替换了div的内容(在你的情况下是一个表格)。但是你必须自己调整paginator元素的active-class。我希望这会让你朝着正确的方向 – Oliver

+0

你也可以在[sandbox](http://sandbox.dereuromark.de/sandbox/ajax-examples)上查看一个非常简单的例子 - 它表明你可以使它变得干净,与一个非JS后备包括在案件JS由于某种原因不工作:) – mark

回答

1

由于的Pagination变化与每个请求的状态 - 一个/下一个环节可能变为无效/主动和数字可能会被截断/发布 - 我建议也呈现在分页您的Ajax请求。

  1. 将您的可替换输出移动到Elements以保持DRY

/src/Template/Element/Acronyms/list.ctp

<?php foreach ($acronyms as $acronym): ?> 
    <tr id = "<?= $acronym->id ?>" name = "<?= $acronym->id ?>"> 
     <td style="display:none;"><?= $acronym->id ?></td> 
     <td style="padding-left:10px;" id="acronymName-<?= $acronym->id ?>" name="acronymName-<?= $acronym->id ?>" ><?= $acronym->abbreviation ?></td> 
     <td style="padding-left:10px;" id="acronymDef-<?= $acronym->id ?>" name="acronymDef-<?= $acronym->id ?>"><?= $acronym->full_text ?></td>          

    </tr> 
<?php endforeach; ?> 

/src/Template/Element/Acronyms/pagination.ctp

<div class="pagination pagination-large"> 
    <ul class="pagination"> 
     <?php 
      echo $this->Paginator->prev(__('prev'), array('tag' => 'li'), null, array('tag' => 'li','class' => 'disabled','disabledTag' => 'a')); 
      echo $this->Paginator->numbers(array('separator' => '','currentTag' => 'a', 'currentClass' => 'active','tag' => 'li','first' => 1)); 
      echo $this->Paginator->next(__('next'), array('tag' => 'li','currentClass' => 'disabled'), null, array('tag' => 'li','class' => 'disabled','disabledTag' => 'a')); 
     ?> 
    </ul> 
</div> 

然后,在你的看法用Elements替换适当的代码:

<?= $this->element('Acronyms/list', ['acronyms' => $acronyms]) ?> 
<?= $this->element('Acronyms/pagination') ?> 
  1. 在您的index方法中为Ajax请求创建一个View

/src/Template/Acronyms/ajax/index.ctp

<table id="list"> 
    <?= $this->element('Acronyms/list', ['acronyms' => $acronyms]) ?> 
</table> 
<div id="pagination"> 
    <?= $this->element('Acronyms/pagination') ?> 
</div> 
  • 检查Ajax请求,并呈现在你ControllerView
  • /src/Controller/AcronymsController.php

    public function index() { 
        $this->loadModel('Acronyms');  
        $acronyms = $this->Acronyms->find('All')->where();  
        $this->set([ 
        'acronyms' => $this->paginate($acronyms), 
        '_serialize' => ['acronyms'] 
        ]); 
    
        // render our View for Ajax requests 
        if ($this->request->is('ajax')) { 
         $this->render('ajax/index'); 
        } 
    } 
    
  • 最后侦听分页链接click事件和更换的内容。
  • jQuery的

    $(document).on('click', '.pagination a', function(e) { 
        e.preventDefault(); 
    
        var $link = $(this); 
    
        if (!$('body').hasClass('loading')) { 
         $('body').addClass('loading'); 
    
         $.ajax({   
          url: $link.attr('href')   
         }).done(function(html) { 
    
          var $html; 
    
          // grab Ajax response into jQuery object 
          $html = $(html); 
    
          // replace table body content with new <tr> elements 
          $('#acronymTable tbody').html($html.find('#list').html()); 
    
          // replace pagination 
          $('#acronymTable .pagination').replaceWith($html.find('#pagination').children()); 
    
          $('body').removeClass('loading'); 
    
         }).fail(function() { 
    
          // if Ajax request fails fall back to just loading the target page 
          window.location.href = $link.attr('href'); 
    
         }); 
        } 
    
    }); 
    
    +0

    谢谢,这是非常有用的。 +1注重细节和彻底! – jason