Pagination prob in Grails

2019-09-19 06:28发布

问题:

I want to display all games under a certain category in pagination (10/page) This is my controller

def listGame(){
    def category = GameCategory.list()
    def platform = Platform.list()
    def currentCategory = params.categoryName
    def myCategory=GameCategory.findByCategoryName(currentCategory)
    def games = myCategory.games

    [currentCategory:currentCategory, category:category, games:games,  platforms:platform, gameCount:Game.count(), chosenPlatform:params.platform] 
}

and this is my pagination code in my view

<g:each in="${games}" status="i" var="game">
    ${game.gameTitle}
</g:each>
<div class="pagination">
            <g:paginate action="listGame" total="${gameCount}" />
</div>

When I have 9 games in the current category the page 12 showed up wherein it shouldn't

When I have 11 games in the current category all 11 games are displayed in page 1 and clicking page 2 will result in this error

回答1:

There are a couple of things to address.

  1. Make sure categoryName is not coming into the controller as null.
  2. Make use of the max and offset parameters that the paginator is providing to select the appropriate Games.

The category name

Because the paginator is creating the URL that calls into the controller, and your controller needs the category name, the paginator must add the category name to the params it calls the controller action with. You can achieve this with the tag's params attribute:

<g:paginate action="listGame" total="${gameCount}" params="${[categoryName: currentCategory]}"/>

Max & offset

The controller needs to use max and offset parameters to know what subset of the Games to retrieve from the database and render in the view. However, in some cases, such as when visiting the URL http://blah/someController/listGame, there would be no max and offset params. This is something your controller action must be able to handle. It goes something like this:

def max = params.max ?: 10
def offset = params.offset ?: 0

So the max and offset params will be used if they are available. Otherwise they'll use default values.

Finally, you need to use these parameters to select the Games. For that you can use a where query:

def games = Game.where {
    categories.categoryName == currentCategory
}.list(max: max, offset: offset)

Something interesting about the returned games object: It acts like a list, but it's actually a grails.gorm.PagedResultList. That's a good thing because it contains the total number of records in the result (ignoring max and offset). In other words, it's your new gameCount.

You can read more about where queries in the Grails documentation. I also have a series of articles which cover where, criteria and HQL queries in more detail.

Putting it all together, listGame() would look like this:

def listGame(){
    def category = GameCategory.list()
    def platform = Platform.list()
    def currentCategory = params.categoryName
    def max = params.max ?: 10
    def offset = params.offset ?: 0
    def games = Game.where {
        categories.categoryName == currentCategory
    }.list(max: max, offset: offset)

    [currentCategory:currentCategory, category:category, games:games,  platforms:platform, gameCount:games.totalCount, chosenPlatform:params.platform] 
}


回答2:

Looks like you haven't done your homework. Please go through grails doc and other tutorials, to understand how pagination works.

Just to give you a hint. You are doing two things wrong here.

  1. You are not getting a paginated list at the first place from controller
  2. You are not sending back all the required data back to the controller, from the pagination link. And that's the reason you are getting the error!