假设我有一个具有各种字符串属性的域类(我们称之为人),如下所示:
class Person {
String favoriteColor
String favoriteAnimal
static constraints = {
favoriteColor(nullable: true)
favoriteAnimal(nullable: true)
}
}
我现在仅尝试使用动态脚手架,以了解我听说过很多关于这种强大的快速应用程序开发能力将带我走多远……但是这门课就到此为止了。
问题
问题是 Grails 动态脚手架中的默认行为是索引页面将显示前 X 个条目,每个条目的第一个字段变成一个超链接,允许您查看/编辑该特定项目。
这真的很棒,但遗憾的是,当第一个字段可以为空时,索引页面会列出该条目 - 但是没有链接可以单击以详细查看/编辑该项目。
当然,简单的解决方案是将不可为空的字段作为第一项......但现在我有一个类,它具有所有单个字段都可以为空的属性,并通过自定义验证确保至少一个字段包含某些内容。所以这在这个烦人的边缘情况下不起作用(但这是一个业务需求,没有一个字段我可以保证在这里永远不会为空)。
解决这个问题的 Grails 方法是什么,而不是完全抛弃脚手架?
如果我只需要改变这个控制器的索引功能来解决问题,我想用最少的代码来做这件事,而不必为控制器的其余部分放弃动态脚手架。我真的很喜欢脚手架(和 Grails)的快速原型能力,并且想充分利用这个功能集。
解决方案
使用Dónal 建议 install-templates 的答案,我只需运行grails install-templates
命令,然后转到我的项目 src->templates->scaffolding->index.gsp 文件。虽然它充满了 scriptlet 等,使其有点难以理解,但事实证明该解决方案非常简单。
在表格部分的 html 中,有一些类似于此的代码:
<table>
<thead>
<tr>
<% excludedProps = Event.allEvents.toList() << 'id' << 'version'
...
通过简单地将其更改为以下内容,您可以获得编辑功能的额外标题行:
<table>
<thead>
<tr>
<th> </th>
<% excludedProps = Event.allEvents.toList() << 'id' << 'version'
...
然后降低您的代码,例如:
<g:each in="\${${propertyName}List}" status="i" var="${propertyName}">
<tr class="\${(i % 2) == 0 ? 'even' : 'odd'}">
<% props.eachWithIndex { p, i ->
if (i == 0) { %>
<td><g:link action="show" id="\${${propertyName}.id}">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</g:link></td>
通过一个简单的更改来摆脱第一个属性名称列上的链接,而是将您自己的编辑链接添加到第一列,问题得到解决:
<g:each in="\${${propertyName}List}" status="i" var="${propertyName}">
<tr class="\${(i % 2) == 0 ? 'even' : 'odd'}">
<% props.eachWithIndex { p, i ->
if (i == 0) { %>
<td><g:link action="show" id="\${${propertyName}.id}">Edit</g:link></td>
<td>\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</td>
因此,通过更改一行并将两行添加到单个文件(在 Grails 命令之后),您已经更改了默认脚手架行为以适应您的喜好并支持可为空的字段。问题解决了!