【问题标题】:Apply defaults to command object based on configuration service根据配置服务将默认值应用于命令对象
【发布时间】:2014-05-05 13:53:04
【问题描述】:

如何在 Grails 2.3 中为命令对象应用默认值?

请注意,当未指定相应的 url 参数时,我需要从服务中检索这些默认值。

我有以下命令对象作为我的操作的参数

class SearchCommand {

    int page
    int pageSize     // todo: get default from configurationService

    String orderBy   // todo: get default from configurationService
    String search

}

我查看了@BindUsing,但在缺少相应的请求参数时似乎没有调用它,这使我尝试应用默认值失败。

【问题讨论】:

    标签: grails grails-2.3


    【解决方案1】:

    你也可以这样做:

    一个控制器..

    // grails-app/controllers/com/demo/DemoController.groovy
    
    package com.demo
    
    class DemoController {
    
        def createPerson(Person p) {
            render "First Name: ${p.firstName}, Last Name: ${p.lastName}"
        }
    }
    
    class Person {
        String firstName
        String lastName
    }
    

    一项服务...

    // grails-app/services/com/demo/MyConfigurationService.groovy
    
    package com.demo
    
    class MyConfigurationService {
    
        def initializePerson(Person p) {
            p.firstName = 'Default First Name'
            p.lastName = 'Default Last Name'
        }
    }
    

    一个绑定监听器...

    // src/groovy/com/demo/PersonBindingListener.groovy
    package com.demo
    
    import org.grails.databinding.events.DataBindingListenerAdapter
    
    class PersonBindingListener extends DataBindingListenerAdapter {
    
        def configService
    
        Boolean beforeBinding(Object target, Object errors) {
            configService.initializePerson target
            true
        }
    
    
        boolean supports(Class<?> clazz) {
            clazz == Person
        }
    }
    

    注册监听器 bean...

    // grails-app/conf/spring/resources.groovy
    
    beans = {
        myListener(com.demo.PersonBindingListener) {
            configService = ref('myConfigurationService')
        }
    }
    

    【讨论】:

    • 在这个例子中,MyConfigurationService 并没有真正添加任何东西。该代码也可以在绑定侦听器中。我展示了使用服务进行初始化,因为 OP 在问题中明确要求这样做。如果服务没有添加任何附加值,您可能只需要监听器中的代码。
    【解决方案2】:

    这里没有足够的信息来确定最好的做法是什么,但您有多种选择。无法告诉该框架,当它创建命令对象的实例时,它应该初始化来自某个服务的属性,但您仍然可以使用您的服务来提供帮助。

        class MyController {
    
            // there is no way to cause co to automatically be 
            // initialized with values from your service...
            def someAction(MyCommand co) {
    
            }
    
            // something like this might help...
            def someOtherAction() {
                // the service creates an instance of the object
                // and initializes values with
                def myCommand = someService.createCommand()
    
                // this will do data binding, overriding the default
                // values defined by the service with values that are
                // included in request params...
                bindData myCommand, params
    
                myCommand.validate()
    
                // carry on...
            }
        }
    

    希望对你有帮助。

    【讨论】:

    • 我试图避免在每个控制器/动作中处理它。我希望一些自定义数据绑定可以解决问题:/
    • 原来 DataBindingListenerAdapter 和实现 afterBinding 可以解决问题。
    • 当前面的评论出现时,我正在输入冗长的第二个答案。我不确定您为什么更喜欢 afterBinding 而不是 beforeBinding,但如果这适用于您的应用,那就太好了。
    • 在afterBinding中只需要从request中查询没有绑定的properties上的configurationService即可。但是,是的,这是“几乎没有区别”的情况:)
    【解决方案3】:

    @Jeff 上面的回答很棒。我根据该答案选择了一个更简单的解决方案:

    鉴于问题中的设置...:

    package com.whatevs
    
    import org.grails.databinding.events.DataBindingListenerAdapter
    
    /**
     * Binds the SearchCommand defaults
     */
    class SearchCommandBindingListener extends DataBindingListenerAdapter{
    
        String ORDER_BY = 'lastName, firstName'
        int PAGE_SIZE = 100
    
        Boolean beforeBinding(Object target, Object errors) {
            SearchCommand searchCommand = (SearchCommand) target
            searchCommand.pageSize = PAGE_SIZE
            searchCommand.orderBy = ORDER_BY
            true
        }
    
        boolean supports(Class<?> clazz) {
            clazz == SearchCommand
        }
    }
    

    在 resources.groovy 中

    searchCommandBindingListener(SearchCommandBindingListener)
    

    您也可以在 resources.groovy 中覆盖 ORDER_BYPAGE_SIZE 的值。

    searchCommandBindingListener(SearchCommandBindingListener) {
        ORDER_BY = 'firstName, lastName'
        PAGE_SIZE = 41
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      相关资源
      最近更新 更多