0

私は主にCRUDであるユーザーコントローラーを持っており、春のツールスイートはcrudの基本的な機能ビューを自動生成できます。

package rms

import org.springframework.dao.DataIntegrityViolationException

class UserController {

static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

def index() {
    redirect(action: "list", params: params)
}

def list(Integer max) {
    params.max = Math.min(max ?: 10, 100)
    [userInstanceList: User.list(params), userInstanceTotal: User.count()]
}

def create() {
    [userInstance: new User(params)]
}

def save() {
    def userInstance = new User(params)
    if (!userInstance.save(flush: true)) {
        render(view: "create", model: [userInstance: userInstance])
        return
    }

    flash.message = message(code: 'default.created.message', args: [message(code: 'user.label', default: 'User'), userInstance.id])
    redirect(action: "show", id: userInstance.id)
}

def show(Long id) {
    def userInstance = User.get(id)
    if (!userInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), id])
        redirect(action: "list")
        return
    }

    [userInstance: userInstance]
}

def edit(Long id) {
    def userInstance = User.get(id)
    if (!userInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), id])
        redirect(action: "list")
        return
    }

    [userInstance: userInstance]
}

def update(Long id, Long version) {
    def userInstance = User.get(id)
    if (!userInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), id])
        redirect(action: "list")
        return
    }

    if (version != null) {
        if (userInstance.version > version) {
            userInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                      [message(code: 'user.label', default: 'User')] as Object[],
                      "Another user has updated this User while you were editing")
            render(view: "edit", model: [userInstance: userInstance])
            return
        }
    }

    userInstance.properties = params

    if (!userInstance.save(flush: true)) {
        render(view: "edit", model: [userInstance: userInstance])
        return
    }

    flash.message = message(code: 'default.updated.message', args: [message(code: 'user.label', default: 'User'), userInstance.id])
    redirect(action: "show", id: userInstance.id)
}

def delete(Long id) {
    def userInstance = User.get(id)
    if (!userInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), id])
        redirect(action: "list")
        return
    }

    try {
        userInstance.delete(flush: true)
        flash.message = message(code: 'default.deleted.message', args: [message(code: 'user.label', default: 'User'), id])
        redirect(action: "list")
    }
    catch (DataIntegrityViolationException e) {
        flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'user.label', default: 'User'), id])
        redirect(action: "show", id: id)
    }
}
}

次に、ビュー/ユーザーの下ではなく、作成した別の gsp でそのメソッドを使用しようとしました。自動生成されたビュー/ユーザー/リストからテーブル html とページネーション html コードをコピーしました。私自身の見解では、残りは静的な html ヘッダーとフッターにすぎないため、重要ではありません。

<table>
            <thead>
                <tr>

                    <g:sortableColumn property="username" title="${message(code: 'user.username.label', default: 'Username')}" />

                    <g:sortableColumn property="password" title="${message(code: 'user.password.label', default: 'Password')}" />

                    <g:sortableColumn property="dateOfBirth" title="${message(code: 'user.dateOfBirth.label', default: 'Date Of Birth')}" />

                    <g:sortableColumn property="contactNumber" title="${message(code: 'user.contactNumber.label', default: 'Contact Number')}" />

                    <g:sortableColumn property="employeeID" title="${message(code: 'user.employeeID.label', default: 'Employee ID')}" />

                    <g:sortableColumn property="employeeStatus" title="${message(code: 'user.employeeStatus.label', default: 'Employee Status')}" />

                </tr>
            </thead>
            <tbody>
            <g:each in="${userInstanceList}" status="i" var="userInstance">
                <tr class="${(i % 2) == 0 ? 'even' : 'odd'}">

                    <td><g:link action="show" id="${userInstance.id}">${fieldValue(bean: userInstance, field: "username")}</g:link></td>

                    <td>${fieldValue(bean: userInstance, field: "password")}</td>

                    <td><g:formatDate date="${userInstance.dateOfBirth}" /></td>

                    <td>${fieldValue(bean: userInstance, field: "contactNumber")}</td>

                    <td>${fieldValue(bean: userInstance, field: "employeeID")}</td>

                    <td>${fieldValue(bean: userInstance, field: "employeeStatus")}</td>

                </tr>
            </g:each>
            </tbody>
        </table>
        <div class="pagination">
            <g:paginate total="${userInstanceTotal}" />
        </div>

自分のビューで並べ替え可能な列を使用するたびに、ビュー/ユーザー/リストにリダイレクトされ、ページネーションは合計の値である userInstanceTotal を見つけることができません。自分のビューにもデータはありませんが、ビュー/ユーザー/作成で作成した後、作成されたデータは自動生成されたCRUDビュー/ユーザー/リストで機能しています

4

2 に答える 2

0

従来の要求/応答アプリケーションでは、list()2 つの異なる GSP に対して同じコントローラー アクション (例: ) を使用する場合、コントローラー アクションに条件を配置して、レンダリングするページを決定する必要がありますrequest.getHeader('referer')。 param を使用して、現在のページを特定します。ただし、単一責任の原則に違反するため、これはお勧めしません。代わりに、次のような別のコントローラー メソッドを作成することを選択します。

ユーザーコントローラーで

  myList(Integer max){
    params.max = Math.min(max ?: 10, 100)
    return [userInstanceList: User.list(params), userInstanceTotal: User.count()]
  }

これはあまり DRY ではありませんが、要件がより複雑になった場合は、共通部分をサービスに移動できます。

myList.gsp 内

にコピーlist.gspmyList.gspます。ページネーションタグ以外はすべて同じです。ページネーションタグを変更して含めますaction

<g:paginate action='myList' total="${userInstanceTotal}" />

の追加に注意してくださいaction='myList'。これを指定しない場合、デフォルトでlist()

于 2013-09-26T16:57:22.240 に答える
0

Grails は、デフォルトで現在のコントローラーのアクションを使用します。

controllerおよびaction属性を使用して、ほとんどのタグでこの動作をオーバーライドできます。たとえば、<g:paginate />は次の属性をサポートしています。

<g:paginate controller="user" action="list" total="${userInstanceTotal}" />

この場合UserController.list()、次/前のページを受け取るために呼び出されます。

残念ながら、<g:sortableColumn />タグにはこれらの属性がないようです。ただし、名前付き URL マッピングmappingを参照するために使用できる属性をサポートしています。

static mappings = {
    name userList: "/userList" {
    controller = 'user'
    action = 'list'
}

<g:sortableColumn mapping="userList" .. />
于 2013-09-24T18:13:39.523 に答える