Grails Scaffolding Templates - 从域类中获取属性
Posted
技术标签:
【中文标题】Grails Scaffolding Templates - 从域类中获取属性【英文标题】:Grails Scaffolding Templates - get properties from domain class 【发布时间】:2016-07-09 11:13:33 【问题描述】:我正在处理我的脚手架模板,更具体地说是 create.gsp 文件。我想获得在我的类中定义的属性。我在网上看到很多关于如何做到这一点的帖子,但似乎没有一个有效。
尝试了以下方法 (grails templates - scaffolding controller):
<%
domainClass.properties.each
println " $it.type $it.name"
%>
使用 generate-all 时出现以下错误:
Error occurred running Grails CLI: No such property: domainClass for class: groovy.lang.Binding
也试过这种方法:
<% import grails.persistence.Event %>
<%
excludedProps = Event.allEvents.toList() << 'version' << 'dateCreated' << 'lastUpdated'
persistentPropNames = domainClass.persistentProperties*.name
props = domainClass.properties.findAll persistentPropNames.contains(it.name) && !excludedProps.contains(it.name) && (domainClass.constrainedProperties[it.name] ? domainClass.constrainedProperties[it.name].display : true)
Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
for (p in props) %>
<g:message code="$domainClass.propertyName.$prefix$p.name.label" default="$p.naturalName" />
<% %>
使用 generate-all 时出现以下错误:
Error occurred running Grails CLI: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed:
GStringTemplateScript4.groovy: 2: Unknown type: IMPORT at line: 2 column: 54. File: GStringTemplateScript4.groovy @ line 2, column 54.
turn out -> out << """"""; import gra
是我遗漏了什么还是 Grails 3 的方法不同?
使用 Grails 3.0.11 版
感谢您的帮助!
【问题讨论】:
Variables available in grails templates的可能重复 查看此答案以了解您的问题:***.com/a/34648837/1799527 【参考方案1】:我使用的是 grails 3.2.4 版本,脚手架插件使用字段插件。在 build.gradle 文件中添加插件如下。
dependencies
...
compile "org.grails.plugins:scaffolding"
...
使用命令安装模板
grails install-form-fields-templates
在文件夹 src/main/templates/scaffolding 中创建以下文件
AsyncController.groovy AsyncSpec.groovy Controller.groovy 创建.gsp edit.gsp index.gsp ScaffoldedController.groovy show.gsp Spec.groovy我已将所有视图自定义为看起来像 twitter boostrap。要呈现字段,它使用字段插件。在 index.gsm 视图中,我想自定义表格渲染,将 g:table 标记替换为我的自定义代码。
这是表格渲染的生成部分。
<f:table collection="\$$propertyNameList" />
这是我的自定义代码,基于 previos grails 版本上的 previos 脚手架代码,适用于在 grails 3.2.4 版本上运行。
<table class="table table-striped">
<thead>
<tr>
<%
def grailsApplication = grails.util.Holders.grailsApplication
domainObjetc = grailsApplication.domainClasses.find it.clazz.simpleName == className .clazz.newInstance()
domainClass= grailsApplication.getDomainClass(domainObjetc.class.name)
excludedProps = grails.persistence.Event.allEvents.toList() << 'id' << 'version'
allowedNames = domainClass.persistentProperties*.name << 'dateCreated' << 'lastUpdated'
props = domainClass.properties.findAll allowedNames.contains(it.name) && !excludedProps.contains(it.name) && it.type != null && !Collection.isAssignableFrom(it.type)
comparator = new org.grails.validation.DomainClassPropertyComparator(domainClass)
Collections.sort(props, comparator)
props.eachWithIndex p, i ->
if (i < 6)
if (p.isAssociation())
%><th class="header"><g:message code="$domainClass.propertyName.$p.name.label" default="$p.naturalName" /></th><%
else
%><g:sortableColumn property="$p.name" title="\$message(code: '$domainClass.propertyName.$p.name.label', default: '$p.naturalName')" /><%
%>
<th></th>
</tr>
</thead>
<tbody>
<g:each in="\$$propertyNameList" var="$propertyName">
<tr>
<% props.eachWithIndex p, i ->
if (i < 6)
if (p.type == Boolean || p.type == boolean) %>
<td><g:formatBoolean boolean="\$$propertyName.$p.name" /></td>
<% else if (p.type == Date || p.type == java.sql.Date || p.type == java.sql.Time || p.type == Calendar) %>
<td><g:formatDate date="\$$propertyName.$p.name" /></td>
<% else %>
<td>\$fieldValue(bean: $propertyName, field: "$p.name")</td>
<% %>
<td class="link">
<div class="btn-group btn-group-xs">
<g:link action="show" id="\$$propertyName.id" class="btn btn-primary btn-sm" role="button">
<span class="glyphicon glyphicon-eye-open"></span>
<g:message code="default.button.show.label" default="Show" />
</g:link>
<g:link action="edit" id="\$$propertyName.id" class="btn btn-primary btn-sm" role="button">
<span class="glyphicon glyphicon-pencil"></span>
<g:message code="default.button.edit.label" default="Edit" />
</g:link>
</div>
</td>
</tr>
</g:each>
</tbody>
</table>
grails 3 中的脚手架插件,使用 GStringTemplateEngine 渲染视图,模板中不允许导入,跳过使用它们并使用完整的包位置,例如在模板内的 Holders 类中检索 grailsApplication您必须使用 grails.util.Holders.grailsApplication 访问它们。
排序需要实现的属性,在上面的代码中被注释为TODO任务。
更新: 可以使用 DomainClassPropertyComparator 类对属性进行排序,使用 grails 3.1 进行测试
希望对你有用。
【讨论】:
在 Grails 3.3.10 上试过,但没有这样的属性:grails for class:groovy.lang.Binding,在访问 grails.* 包时发生。此外,DomainClassPropertyComparator 在 3.3.10 中已弃用。检查github.com/grails/grails-core/issues/… 没错,DomainClassPropertyComparator 在 3.3.10 中已弃用。【参考方案2】:在 Grails 4 中,在我的例子中,Grails 4.0.10 要获取域列表,程序必须更改为:
MappingContext mappingContext = grailsApplication.getMappingContext()
def entities = mappingContext.getPersistentEntities()
并具体获取实体:
def entity = mappingContext.getPersistentEntity(fullEntityName)
获取实体的持久属性:
def persistentProperties = entity.getPersistentProperties()
并获得排除的属性:
def excludedProps = Event.allEvents.toList() << 'id' << 'version'
需要导入的库如下:
import grails.artefact.DomainClass
import grails.core.GrailsApplication
import grails.persistence.Event
import org.grails.datastore.mapping.model.MappingContext
因此我们可以遵循之前帖子中建议的相同逻辑!
【讨论】:
以上是关于Grails Scaffolding Templates - 从域类中获取属性的主要内容,如果未能解决你的问题,请参考以下文章