Grails App中的双重分页问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grails App中的双重分页问题相关的知识,希望对你有一定的参考价值。

我在Grails 2.3.11和Groovy 2.1.9上(我现在无法做出升级的决定)。我有一些代码,我从一篇文章中借用来实现ajax列表,在this link中进行分页,过滤和排序

它的工作正常,除了分页。当我按降序排序网格时,我得到两个分页div。当我按升序排序(ajax请求)时,它只是一个div(因为这会导致实际的页面重新加载)。我查看了代码,我看不出为什么ajax请求会导致双重分页。

为简单起见,我在文章中使用相同的代码作为测试,我得到了相同的问题。任何人都可以看到什么是错的?

控制器动作

def list = {
      def query = {
           if (params.name) {
                    ilike('lastName', '%' + params.name + '%')
            }
            if (params.sort){
                order(params.sort,params.order)
            }
     }

     def criteria = User.createCriteria()
     params.max = Math.min(params.max ? params.int('max') : 20, 100)
     def users = criteria.list(query, max: params.max, offset: params.offset)
     def filters = [name: params.name]

     def model = [userInstanceList: users, userInstanceTotal: users.totalCount, filters: filters]

      if (request.xhr) {
          // ajax request
          render(template: "grid", model: model)
      }
      else {
           model
      }
}

的list.gsp

    <html>
        <head>
            <meta name="layout" content="main" />
            <g:set var="entityName" value="${message(code: 'user.label', default: 'User')}" />
            <title><g:message code="default.list.label" args="[entityName]" /></title>
        </head>
        <body>

        <h2><g:message code="default.list.label" args="[entityName]" /></h2>

        <g:if test="${flash.message}">
          <div class="message">${flash.message}</div>
        </g:if>
            <br />
            <div class="filters">
              <g:form action="list">

                  <p><label for="name">Name</label>
                  <g:textField name="name" value="${filters?.name}" /></p>

                  <p><g:submitButton name="filter" value="Filter" /></p>

               </g:form>
            </div>    
            <br />
            <div id="grid">
              <g:render template="grid" model="model" />    
            </div>
            <br />
            <p>
              <g:link action="create"><g:message code="default.new.label" args="[entityName]" /></g:link>
            </p>
<script>
$(document).ready(function() {
    setupGridAjax();
    setupFilterAjax();
});

// Turn all sorting and paging links into ajax requests for the grid
function setupGridAjax() {
    $("#grid").find(".paginateButtons a, th.sortable a").live('click', function(event) {
        event.preventDefault();
        var url = $(this).attr('href');

        var grid = $(this).parents("table.ajax");
        $(grid).html($("#spinner").html());

        $.ajax({
            type: 'GET',
            url: url,
            success: function(data) {
                $(grid).fadeOut('fast', function() {$(this).html(data).fadeIn('slow');});
            }
        })
    });
}

// Turn any input changes or form submission within a filter div into an ajax call
function setupFilterAjax() {
    $('div.filters :input').change(function() {
        var filterBox = $(this).parents("div.filters");
    filterGrid(filterBox);
    });
    $("div.filters form").submit(function() {
    var filterBox = $(this).parents("div.filters");
    filterGrid(filterBox);
        return false;
    });
}

// Reload grid based on selections from the filter
function filterGrid(filterBox) {
     var grid = $(filterBox).next("div.grid");
     $(grid).html($("#spinner").html());

     var form = $(filterBox).find("form");
     var url = $(form).attr("action");
     var data = $(form).serialize();
     $.ajax({
        type: 'POST',
        url: url,
        data: data,
        success: function(data) {
            $(grid).fadeOut('fast', function() {$(this).html(data).fadeIn('slow');});
        }
     });
}
</script>
        </body> 
    </html>

_grid.gsp

<table class="ajax">
    <thead>
        <tr>
            <g:sortableColumn property="id" title="Id" params="${filters}" />
            <g:sortableColumn property="isActive" title="Is Active" params="${filters}" />
            <g:sortableColumn property="name" title="Name" params="${filters}" />
       </tr>
    </thead>
    <tbody>
    <g:each in="${userInstanceList}" status="i" var="userInstance">
        <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
            <td><g:link action="show" id="${userInstance.id}">${fieldValue(bean: userInstance, field: "id")}</g:link></td>
            <td><g:formatBoolean boolean="${userInstance.isActive}" /></td>
            <td>${fieldValue(bean: userInstance, field: "name")}</td>
         </tr>
    </g:each>
    </tbody>
</table>

<div class="pagination">
    <g:paginate total="${userInstanceTotal}" params="${filters}" />
</div>
答案

发布这个问题后我发现了问题(当然)。

这一行:var grid = $(this).parents("table.ajax");

只寻找一个带有ajax类的表。分页div恰好不符合该标准。解决方法是将整个_grid模板代码包装在具有id属性的div中,然后在上面的行中使用该id。它看起来像这样:

var grid = $(this).parents("#idOfNewDiv");

以上是关于Grails App中的双重分页问题的主要内容,如果未能解决你的问题,请参考以下文章

grails框架的g:paginate分页标签的使用

Grails + Spring Security:无法登录

Grails extJS 网格分页

带有片段参数的 Grails render()

没有双重查询的MySQL分页?

从 Grails 中的布局视图访问模型