我正在尝试在我的grails应用程序中创建一个搜索操作,该操作接受许多条件并显示符合条件的实例的表(类似于默认索引操作)。
对于有很多结果的搜索条件,我想使用paginate
标记:
<g:paginate total="${alarmInstanceCount ?: 0}" />
默认情况下,此标记会忘记搜索条件。我相信params
属性允许我将搜索参数添加到paginate标记创建的链接。
要封装我的搜索条件,我已将它们组织到名为searchParams
的地图中。
但是,当我尝试将searchParams传递给paginate标记时:
<g:paginate total="${alarmInstanceCount ?: 0}" params="${[searchParams:searchParams]}"/>
我的searchParams变成了一个字符串。
这是我的意思的一个例子。
当我第一次打开搜索页面时,控制器会报告params
,如下所示:
[action:index, format:null, controller:alarm, max:10]
null
class org.codehaus.groovy.runtime.NullObject
因此,由于params映射不包含searchParams
的条目,因此它出现为null并且具有NullObject
类。我的代码优雅地处理了这个案例。
当我在channelName
字段中输入一些文字时,控制器会报告params
,如下所示:
[searchParams.channelName:SWR, searchParams:[channelName:SWR], _action_index:List, _method:PUT, action:index, format:null, controller:alarm, max:10]
[channelName:SWR]
class org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap
因此,现在params
地图的searchParams
条目引用了GrailsParameterMap
。这是所需的行为,控制器正确解释了这一行为。
但是,如果我点击分页栏中的第一个条目,控制器会按如下方式报告参数:
[max:10, searchParams:[channelName:SWR], offset:10, action:index, format:null, controller:alarm]
[channelName:SWR]
class java.lang.String
在第三种情况下,params
地图的searchParams
条目看起来正确,但实际上是String
对象。这导致我的代码崩溃:
No such property: channelName for class: java.lang.String.
这是paginate标签的params属性的预期行为吗?如果是这样,对我来说,实现我正在寻找的行为的最简洁方法是什么(即searchParams作为地图而不是字符串传递给我的控制器)?
编辑:
以下是我的搜索表单的相关gsp代码:
<g:form url="[action:'index']" method="PUT" >
<fieldset class="form">
<div class="fieldcontain">
<label for="channelName">
<g:message code="alarm.channelName.label" default="Channel Name" />
</label>
<g:textField name="searchParams.channelName" value="${searchParams?.channelName}"/>
</div>
</fieldset>
<fieldset class="buttons">
<g:actionSubmit class="list" action="index" value="${message(code: 'default.button.list.label', default: 'List', args: [entityName])}" />
</fieldset>
</g:form>
这是我的索引动作:
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
def alarmCriteria = new DetachedCriteria(Alarm)
def channelInterfaceInstances = ChannelInterface.list();
if(params.searchParams?.channelName != null && params.searchParams?.channelName != "" && params.searchParams?.channelName != []) {
alarmCriteria = alarmCriteria.and {
like("channelName", "%${params.searchParams?.channelName}%")
}
}
def results = alarmCriteria.list(params) {}
respond results, model:[alarmInstanceCount: results.totalCount, searchParams: params.searchParams]
}