Grails 命令对象数据绑定 [英] Grails command object data binding

查看:17
本文介绍了Grails 命令对象数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Grails 有非常好的支持 用于将请求参数绑定到域对象及其关联.这在很大程度上依赖于检测以 .id 结尾的请求参数并自动从数据库加载这些参数.

Grails has very good support for binding request parameters to a domain object and it's associations. This largely relies on detecting request parameters that end with .id and automatically loading those from the database.

但是,不清楚如何填充命令对象的关联.举个例子:

However, it's not clear how to populate the associations of a command object. Take the following example:

class ProductCommand {

    String name
    Collection<AttributeTypeCommand> attributeTypes 
    ProductTypeCommand productType
}

该对象与 ProductTypeCommand 有单端关联,与 AttributeTypeCommand 有多端关联.所有属性类型和产品类型的列表都可以从这个接口的实现中获得

This object has a single-ended association with ProductTypeCommand and a many-ended association with AttributeTypeCommand. The list of all attribute types and product types are available from an implementation of this interface

interface ProductAdminService {
    Collection<AttributeTypeCommand> listAttributeTypes();
    Collection<ProductTypeCommand> getProductTypes();
}

我使用此界面填充 GSP 中的产品和属性类型选择列表.我还将这个接口依赖注入到命令对象中,并使用它来模拟"命令对象上的 attributeTypesproductType 属性

I use this interface to populate the product and attribute type selection lists in a GSP. I also dependency-inject this interface into the command object, and use it to "simulate" attributeTypes and productType properties on the command object

class ProductCommand {

    ProductAdminService productAdminService

    String name   

    List<Integer> attributeTypeIds = []
    Integer productTypeId

    void setProductType(ProductTypeCommand productType) {
        this.productTypeId = productType.id
    }

    ProductTypeCommand getProductType() {
        productAdminService.productTypes.find {it.id == productTypeId}        
    }

    Collection<AttributeTypeCommand> getAttributeTypes() {

        attributeTypeIds.collect {id ->
            productAdminService.getAttributeType(id)
        }
    }

    void setAttributeTypes(Collection<AttributeTypeCommand> attributeTypes) {
        this.attributeTypeIds = attributeTypes.collect {it.id}
    }
}

实际发生的是 attributeTypeIdsproductTypeId 属性绑定到相关的请求参数,并且 getter/setter 模拟"productTypeattributeTypes 属性.有没有更简单的方法来填充命令对象的关联?

What actually happens is that the attributeTypeIds and productTypeId properties are bound to the relevant request parameters and the getters/setters "simulate" productType and attributeTypes properties. Is there a simpler way to populate the associations of a command object?

推荐答案

你真的需要为 attributeTypes 和 productType 属性设置子命令吗?您不使用 PropertyEditorSupport 绑定的任何原因?例如:

Do you actually need to have sub-commands for attributeTypes and productType properties? Any reason you're not using PropertyEditorSupport binding? E.g.:

public class ProductTypeEditor extends PropertyEditorSupport
{
    ProductAdminService productAdminService // inject somewhow
    void setAsText(String s)
    {
        if (s) value = productAdminService.productTypes.find { it.id == s.toLong() }
    }

    public String getAsText()
    {
        value?.id        
    }
}

(和 attributeType 对象类似的东西),并在编辑器注册器中注册这些:

(and something similar for attributeType object), and register these in a editor registrar:

import java.beans.PropertyEditorSupport
public class CustomEditorRegistrar implements PropertyEditorRegistrar {
    public void registerCustomEditors(PropertyEditorRegistry reg) {
        reg.registerCustomEditor(ProductType, new ProductTypeEditor())
        reg.registerCustomEditor(AttributeType, new AttributeTypeEditor())
    }
}

并在您的 resources.groovy 中注册:

And register in your resources.groovy:

beans =
{
    customEditorRegistrar(CustomEditorRegistrar)
}

然后在您的 Cmd 中:

then in your Cmd you just have:

class ProductCommand {
    String name
    List<AttributeType> attributeTypes = []
    ProductType productType
}

如果您确实需要实际的子命令关联,那么我已经做了一些类似于@Andre Steingress 所建议的,结合 PropertyEditorSupport 绑定:

If you do need actual sub-command associations then I've done something similar to what @Andre Steingress has suggested, in combination with PropertyEditorSupport binding:

// parent cmd
import org.apache.commons.collections.ListUtils
import org.apache.commons.collections.FactoryUtils
public class DefineItemConstraintsCmd implements Serializable
{
    List allItemConstraints = ListUtils.lazyList([], FactoryUtils.instantiateFactory(ItemConstraintsCmd))
    //...
}    
// sub cmd
@Validateable
class ItemConstraintsCmd implements Serializable
{
    Item item // this has an ItemEditor for binding
    //...
}

希望我没有误解你想要达到的目标:)

Hopefully I've not misunderstood what you're trying to achieve :)

这篇关于Grails 命令对象数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆