Шаблоны Grails Scaffolding — получение свойств из доменного класса

Я работаю над своими шаблонами строительных лесов, а точнее над файлом create.gsp. Я хотел бы получить свойства, определенные в моем классе. Я видел много сообщений в Интернете о том, как это сделать, но ни один из них не работает.

Пробовал следующее (шаблоны Grails - контроллер лесов):

<%
    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

Я ценю любую помощь!


person NBabineau    schedule 22.03.2016    source источник
comment
Возможный дубликат переменных, доступных в шаблонах Grails   -  person Sandeep Poonia    schedule 22.03.2016
comment
Посмотрите этот ответ на свой запрос: stackoverflow.com/a/34648837/1799527   -  person Sandeep Poonia    schedule 22.03.2016


Ответы (2)


Я использую версию 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
  • Контроллер.groovy
  • создать.gsp
  • редактировать.gsp
  • index.gsp
  • ScaffoldedController.groovy
  • показать.gsp
  • Spec.groovy

Я настроил все представления так, чтобы они выглядели как Twitter Boostrap. Для рендеринга полей используется плагин fields. В представлении index.gsm я хочу настроить рендеринг таблицы, заменив тег g:table моим собственным кодом.

Это сгенерированная часть для рендеринга таблицы.

 <f:table collection="\${${propertyName}List}" />

Это мой пользовательский код, основанный на предыдущем коде формирования шаблонов в предыдущей версии Grails и адаптированный для работы в версии 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 для визуализации представления, импорт в шаблоне запрещен, пропустите их и используйте полное расположение пакета, например, чтобы получить приложение grailsApplication в классе Holders внутри шаблона, который вы должны получить к ним доступ с помощью grails.util.Holders.grailsApplication.

Необходимо реализовать сортировку свойств, в приведенном выше коде она отмечена как задача TODO.

Обновление: сортировку свойств можно выполнять с помощью класса DomainClassPropertyComparator, протестированного с помощью Grails 3.1.

Я надеюсь быть полезным для вас.

person Jose Luis Bracamonte Amavizca    schedule 29.12.2016
comment
пробовал на Grails 3.3.10 и не получил такого свойства: grails для класса: groovy.lang.Binding, происходит при доступе к пакетам grails.*. Также DomainClassPropertyComparator устарел в 3.3.10. Проверьте github.com/grails/grails-core/issues/ - person Pablo Pazos; 13.05.2020
comment
Это правильно, DomainClassPropertyComparator устарел в 3.3.10. - person Jose Luis Bracamonte Amavizca; 14.05.2020

В 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

Итак, мы можем следовать той же логике, предложенной в предыдущих сообщениях!

person Pedro Gentil    schedule 15.05.2021