【问题标题】:Dynamic abstract Grails Controller动态抽象 Grails 控制器
【发布时间】:2016-04-12 09:20:49
【问题描述】:

我正在使用 Grails 2.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]
    }

}

现在我想要一个扩展 DomainClasscontrollerBarController

class BarController extends DomainClassController {
    def domainClass = Bar
}

如何在每个 Controller 中设置 domainClass 以便抽象控制器可以将其用于索引和搜索方法?

编辑

我按照答案中的描述进行操作以使其正常工作。 但现在我想让 create Method 动态化,所以我添加了这个:

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

    return render(view: getViewPath() + 'create', model: [domainClass: domainClassObject])
}

这项工作本身也可以,但我不想在 GSP 中使用属性domainClass。我想在 Lower Cas 中使用类名,所以 f.e. foo 用于视图中的 Foo 类和 bar 用于视图中的 Bar 类。

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

【问题讨论】:

  • 可以使用抽象方法代替属性。
  • 与您的问题无关,但不是ApplicationContext context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContextConfigObject config = context.getBean(GrailsApplication).config,您可以通过实现GrailsConfigurationAware 并在setConfiguration 方法中初始化config 属性来简化它。您的示例甚至没有使用config,因此尚不清楚您为什么需要其中任何一个。

标签: grails


【解决方案1】:

您可以像RestfulController 那样做。见https://github.com/grails/grails-core/blob/v2.5.4/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy

名为resourceClass 属性在https://github.com/grails/grails-core/blob/d45c00be6d8fdcce3edd21e16b50e30df9151b58/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy#L37 中定义。在该Class 上调用newInstance() 方法以创建一个新实例。见https://github.com/grails/grails-core/blob/d45c00be6d8fdcce3edd21e16b50e30df9151b58/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy#L267

class RestfulController<T> {

    Class<T> resource
    String resourceName
    String resourceClassName
    boolean readOnly

    // ...

    RestfulController(Class<T> resource) {
        this(resource, false)
    }

    RestfulController(Class<T> resource, boolean readOnly) {
        this.resource = resource
        this.readOnly = readOnly
        resourceClassName = resource.simpleName
        resourceName = GrailsNameUtils.getPropertyName(resource)
    }

    // ...

    /**
     * Lists all resources up to the given maximum
     *
     * @param max The maximum
     * @return A list of resources
     */
    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond listAllResources(params), model: [("${resourceName}Count".toString()): countResources()]
    }

    /**
     * Creates a new instance of the resource.  If the request
     * contains a body the body will be parsed and used to
     * initialize the new instance, otherwise request parameters
     * will be used to initialized the new instance.
     *
     * @return The resource instance
     */
    protected T createResource() {
        T instance = resource.newInstance()
        bindData instance, getObjectToBind()
        instance
    }

    /**
     * List all of resource based on parameters
     *
     * @return List of resources or empty if it doesn't exist
     */
    protected List<T> listAllResources(Map params) {
        resource.list(params)
    }

    /**
     * Counts all of resources
     *
     * @return List of resources or empty if it doesn't exist
     */
    protected Integer countResources() {
        resource.count()
    }
}

【讨论】:

    【解决方案2】:

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

    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]
        }
    
    }
    

    BarController.groovy

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

    【讨论】:

      猜你喜欢
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 2012-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多