【问题标题】:Grails Scaffolding Templates - get properties from domain classGrails Scaffolding Templates - 从域类中获取属性
【发布时间】: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 版

感谢您的帮助!

【问题讨论】:

标签: grails grails-3.0


【解决方案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="\${${propertyName}List}" />

这是我的自定义代码,基于 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="\${${propertyName}List}" 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

因此我们可以遵循之前帖子中建议的相同逻辑!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 2012-08-30
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多