2016-04-12 2 views
0

Я использую Grails 2.4.3, и я пытаюсь создать динамический абстрактный контроллер класса домена, который содержит несколько стандартных методов, которые могут использоваться каждым классом домена.Динамический абстрактный контроллер Grails

Так что я создал 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, что расширяет DomainClasscontroller:

class BarController extends DomainClassController { 
    def domainClass = Bar 
} 

Как я могу установить domainClass в каждом контроллере, что абстрактный контроллер может использовать его для индекс и метод поиска?

EDIT

Я сделал это так, как это описано в ответе, чтобы получить его работу. Но теперь я хочу, чтобы сделать метод создания динамики, так что я добавил это:

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 в lowerCase?

+1

Вместо свойства вы можете использовать абстрактный метод. –

+0

Не связанный с вашей проблемой, а вместо 'ApplicationContext context = ServletContextHolder.servletContext.getAttribute (GrailsApplicationAttributes.APPLICATION_CONTEXT) в качестве ApplicationContext' и' ConfigObject config = context.getBean (GrailsApplication) .config' вы могли бы упростить это путем реализации «GrailsConfigurationAware» и инициализируя свойство 'config' в методе' setConfiguration'. В вашем примере даже не используется 'config', поэтому не понятно, зачем вам это нужно. –

ответ

1

Вы могли бы d o это так же, как RestfulController. См. https://github.com/grails/grails-core/blob/v2.5.4/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy.

A Class Недвижимость с именем resource определено по адресу https://github.com/grails/grails-core/blob/d45c00be6d8fdcce3edd21e16b50e30df9151b58/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy#L37. Метод newInstance() вызывается на этом Class для создания нового экземпляра. См. 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() 
    } 
} 
1

Вы можете установить класс домена в каждом контроллере (подкласс), и сделать его доступным для абстрактного класса, путем его реализации в качестве абстрактного метода:

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  
    } 
} 
+0

Это работает спасибо. – YAT

Смежные вопросы