动态抽象Grails控制器

动态抽象Grails控制器,grails,Grails,我正在使用Grails2.4.3,并试图创建一个动态抽象域类控制器,其中包含一些标准方法,每个域类都可以使用这些方法 因此,我创建了DomainClassController abstract class DomainClassController { def domainClassSearchService def domainClass = Foo ApplicationContext context = ServletContextHolder.servletConte

我正在使用Grails2.4.3,并试图创建一个动态抽象域类控制器,其中包含一些标准方法,每个域类都可以使用这些方法

因此,我创建了
DomainClassController

abstract class DomainClassController {
    def domainClassSearchService

 def domainClass = Foo
    ApplicationContext context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContext
    ConfigObject config = context.getBean(GrailsApplication).config

    def index() { 

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)
        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)
        render view: 'index', model: [list: list, count: count]
    }

    def search() {

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)

        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)

        render template: 'list', model: [list: list, count: count, params: params]
    }

}
现在,我想要一个扩展
域类控制器的
BarController

class BarController extends DomainClassController {
    def domainClass = Bar
}
如何在每个控制器中设置domainClass,抽象控制器可以将其用于索引和搜索方法

编辑

我按照答案中描述的那样做是为了让它工作。 但是现在我想使create方法动态化,所以我添加了以下内容:

def create(){
    def domainClassObject = getDomainClass()?.newInstance()
    domainClassObject.properties = params

    return render(view: getViewPath() + 'create', model: [domainClass: domainClassObject])
}
这本身也是可行的,但我不想在GSP中使用属性
domainClass
。我想在较低的Cas中使用类名,以便在视图中为类
foo
使用f.e.
foo
,为类
bar
使用
bar


如何将模型名设置为小写的类名?

您可以在每个控制器(子类)中设置域类,并通过将其实现为抽象方法使抽象类可以访问它:

DomainClassController.groovy

abstract class DomainClassController {
    def domainClassSearchService

    ApplicationContext context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContext
    ConfigObject config = context.getBean(GrailsApplication).config

    abstract Class getDomainClass()

    def index() { 

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)
        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)
        render view: 'index', model: [list: list, count: count]
    }

    def search() {

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)

        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)

        render template: 'list', model: [list: list, count: count, params: params]
    }

}
class BarController extends DomainClassController {
    Class getDomainClass() {
        Bar    
    }
}
BarController.groovy

abstract class DomainClassController {
    def domainClassSearchService

    ApplicationContext context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContext
    ConfigObject config = context.getBean(GrailsApplication).config

    abstract Class getDomainClass()

    def index() { 

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)
        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)
        render view: 'index', model: [list: list, count: count]
    }

    def search() {

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)

        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)

        render template: 'list', model: [list: list, count: count, params: params]
    }

}
class BarController extends DomainClassController {
    Class getDomainClass() {
        Bar    
    }
}

您可以在每个控制器(子类)中设置域类,并通过将其实现为抽象方法使抽象类可以访问它:

DomainClassController.groovy

abstract class DomainClassController {
    def domainClassSearchService

    ApplicationContext context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContext
    ConfigObject config = context.getBean(GrailsApplication).config

    abstract Class getDomainClass()

    def index() { 

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)
        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)
        render view: 'index', model: [list: list, count: count]
    }

    def search() {

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)

        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)

        render template: 'list', model: [list: list, count: count, params: params]
    }

}
class BarController extends DomainClassController {
    Class getDomainClass() {
        Bar    
    }
}
BarController.groovy

abstract class DomainClassController {
    def domainClassSearchService

    ApplicationContext context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContext
    ConfigObject config = context.getBean(GrailsApplication).config

    abstract Class getDomainClass()

    def index() { 

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)
        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)
        render view: 'index', model: [list: list, count: count]
    }

    def search() {

        if (!domainClass)
            return render(text: 'fehler', status: INTERNAL_SERVER_ERROR)

        def list = domainClassSearchService.list(params, domainClass, params.max, params.offset, params.sort, params.order)
        Integer count = domainClassSearchService.count(params, domainClass)

        render template: 'list', model: [list: list, count: count, params: params]
    }

}
class BarController extends DomainClassController {
    Class getDomainClass() {
        Bar    
    }
}

您可以使用与
RestfulController
相同的方法来执行此操作。看

名为
resource
Class
属性在中定义。在该
类上调用
newInstance()
方法来创建新实例。看

类RestfulController{
类资源
字符串资源名
字符串resourceClassName
布尔只读
// ...
RestfulController(类资源){
此(资源,错误)
}
RestfulController(类资源,布尔只读){
this.resource=resource
this.readOnly=readOnly
resourceClassName=resource.simpleName
resourceName=GrailsNameUtils.getPropertyName(资源)
}
// ...
/**
*列出给定最大值之前的所有资源
*
*@param max最大值
*@返回资源列表
*/
def索引(最大整数){
params.max=Math.min(max?:10100)
respond listalresources(params),模型:[(${resourceName}Count.toString()):countResources()]
}
/**
*创建资源的新实例。如果
*包含一个主体,主体将被解析并用于
*初始化新实例,否则请求参数
*将用于初始化新实例。
*
*@返回资源实例
*/
受保护的createResource(){
T instance=resource.newInstance()
bindData实例,getObjectToBind()
实例
}
/**
*根据参数列出所有资源
*
*@返回资源列表,如果不存在则为空
*/
受保护列表listAllResources(映射参数){
资源列表(参数)
}
/**
*计算所有资源
*
*@返回资源列表,如果不存在则为空
*/
受保护的整数资源(){
resource.count()
}
}

您可以使用与
RestfulController
相同的方法执行此操作。看

名为
resource
Class
属性在中定义。在该
类上调用
newInstance()
方法来创建新实例。看

类RestfulController{
类资源
字符串资源名
字符串resourceClassName
布尔只读
// ...
RestfulController(类资源){
此(资源,错误)
}
RestfulController(类资源,布尔只读){
this.resource=resource
this.readOnly=readOnly
resourceClassName=resource.simpleName
resourceName=GrailsNameUtils.getPropertyName(资源)
}
// ...
/**
*列出给定最大值之前的所有资源
*
*@param max最大值
*@返回资源列表
*/
def索引(最大整数){
params.max=Math.min(max?:10100)
respond listalresources(params),模型:[(${resourceName}Count.toString()):countResources()]
}
/**
*创建资源的新实例。如果
*包含一个主体,主体将被解析并用于
*初始化新实例,否则请求参数
*将用于初始化新实例。
*
*@返回资源实例
*/
受保护的createResource(){
T instance=resource.newInstance()
bindData实例,getObjectToBind()
实例
}
/**
*根据参数列出所有资源
*
*@返回资源列表,如果不存在则为空
*/
受保护列表listAllResources(映射参数){
资源列表(参数)
}
/**
*计算所有资源
*
*@返回资源列表,如果不存在则为空
*/
受保护的整数资源(){
resource.count()
}
}

您可以使用抽象方法代替属性。与您的问题无关,而是将
ApplicationContext context=ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION\u context)作为ApplicationContext
ConfigObject config=context.getBean(GrailsApplication).config
您可以通过实现
GrailsConfigurationAware
并在
setConfiguration
方法中初始化
config
属性来简化这一过程。您的示例甚至没有使用
config
,因此不清楚您为什么需要这些配置