Как показать популяции абстрактных классов в index.gsp - PullRequest
0 голосов
/ 07 мая 2020

В Grails 4.0.3 и Grails 3.3.11, если у вас есть иерархия наследования с абстрактным суперклассом, например,

package mypackage

abstract class A {
  String name
  // ...
  // properties
  // ...
}
package mypackage

class B extends A {
  String b
  // ...
  // properties
  // ...
}
package mypackage

class C extends A {
  String c
  // ...
  // properties
  // ...
}

И вы заполняете конкретные классы в Bootstrap.groovy, например,

package mypackage

class BootStrap {

    def init = { servletContext ->
        A.withTransaction { status ->
            def listOfB = []
            (1..25).each { i ->
                listOfB << new B(name:"b${i}",b:"${i}st")
            }

            B.saveAll( listOfB )

            def listOfC = []
            (1..25).each { i ->
                listOfC << new C(name:"c${i}",c:"${i}nd")
            }

            C.saveAll( listOfC )
        }
    }
    def destroy = {
    }
}

Если вы используете скаффолдинг, страница index для A показывает пустой список вместо разбитого на страницы списка из 50 объектов (25 объектов B и другие 25 C объектов).

Кроме того, он показывает кнопку new , которая генерирует java.lang.InstantiationException при нажатии, потому что пытается создать экземпляр абстрактного класса.

Как я могу показать популяции абстрактные классы в index.gsp?

1 Ответ

0 голосов
/ 07 мая 2020

Решение этой проблемы следующее:

  1. Создание представлений для абстрактного класса (актуально только index.gsp)
  2. Отредактируйте сгенерированный index.gsp следующим образом:

    • Комментарий новый код кнопки
<!-- no create button -->
<!--
<li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
-->
  • Комментарий <f:table> и добавьте следующий код
<!-- new arguments for f:table -->
<g:set var="collection" value="${mypackage.A.list(params)}" />
<g:set var="domainClass" value="${grailsApplication.getDomainClass('mypackage.A')}" />
<g:set var="domainProperties" value="${domainClass.getConstrainedProperties().keySet()}" />
<!-- old f:table -->
<!-- <f:table collection="${aList}" /> -->
<!-- new f:table -->
<f:table collection="${collection}" properties="${domainProperties}" />            

В отношении атрибутов <f:table>:

  • Переменная aList, первоначально переданная в <f:table>, равна null.
  • Не включать domainClass="mypackage.A", он генерирует java.lang.InstantiationException.
  • Атрибут properties должен присутствовать и содержать список свойств только абстрактного класса . Если его нет, и объекты классов A и B появляются в одной и той же разбивке на страницы, выдается org.springframework.beans.NotReadablePropertyException, потому что <f:table> пытается прочитать свойства класса B на объектах класса C и наоборот.

Кроме того, для A по-прежнему доступны страницы create и edit. У меня есть generated-all для A, и я попытался удалить эти методы из сгенерированного контроллера, но мои знания о Grails ограничены, и у меня много ошибок, поэтому я вернулся к созданию лесов (что является моей основной причиной для с использованием Grails).

Я думаю, что Grails не должен показывать пустые списки для абстрактных классов в каркасах, но я не знаю, находится ли это поведение внутри контроллера строительных лесов, тега <f:table> или закодировано в _table.gsp.

Я также считаю, что Grails не должен генерировать методы create и update в контроллерах строительных лесов для абстрактных классов.

...