Grails 数据绑定(bind) - 如何排除子属性

标签 grails groovy data-binding

当我使用 grailsWebDataBinder 时如何排除子域属性?

例如,我有域:

class Car {
   String carPropertyToExclude

   Set<Detail> details

   static hasMany = [details: Detail]
}

class Detail {
   String detailPropertyToExclude

   static belongsTo= [car: Car]
}

当我调用 grailsWebDataBinderbind 方法并给 car 时,我想从 Detail 中排除 detailPropertyToExclude > 实例作为参数

代码:

List blackList = ["carPropertyToExclude"]
grailsWebDataBinder.bind(car, new SimpleMapDataBindingSource(params), null, blackList)

注意: 当从任何地方排除时,不要建议 bindable: false 或变体。只需要知道有没有办法通过提供 blackList 作为 bind() 方法参数来做到这一点。

这些变体也不起作用:

List blackList = ["carPropertyToExclude", "details.detailPropertyToExclude"]
List blackList = ["carPropertyToExclude", [Detail.class : "detailPropertyToExclude"]]

主要问题是如何准备blackList 来排除 child 的属性(property)?

最佳答案

黑名单参数只支持直接对象属性

你可以使用DataBindingListener

import grails.databinding.events.DataBindingListenerAdapter

class BlackListener extends DataBindingListenerAdapter{
    List<String> list
    //returns false if you want to exclude property from binding
    public Boolean beforeBinding(Object obj, String propertyName, Object value, Object errors) {
        return !list.contains("${obj?.class.name}.${propertyName}".toString())
    }
}

...

List blackList = ["Car.carPropertyToExclude", "Details.detailPropertyToExclude"]
grailsWebDataBinder.bind(car, new SimpleMapDataBindingSource(params), 
                new BlackListener(list:blackList) )

更新:

不幸的是,上述方法不适用于 Collection 绑定(bind)。

SimpleDataBinder.setPropertyValue(...)的问题方法在处理列表时丢失 listener

不确定以下解决方法是否有效(可能需要上下文初始化)

但是可以为每个黑名单注册转换器:

import grails.databinding.SimpleDataBinder
import grails.databinding.SimpleMapDataBindingSource
import grails.databinding.converters.ValueConverter

SimpleDataBinder setBlackList(SimpleDataBinder binder, Map<Class,List<String>> blackLists) {
    blackLists.each { Class clazz, List<String> blackList ->
        def vc = new ValueConverter(){
            boolean canConvert(Object value){
                return value instanceof Map
            }
            Object convert(Object value){
                def obj = clazz.newInstance()
                binder.bind( obj, new SimpleMapDataBindingSource(value), [], blackList )
                return obj
            }
            Class<?> getTargetType(){ clazz }
        }
        binder.registerConverter(vc)
    }
    return binder
}

...

Map blackLists = [
    (Car.class)    : ["carPropertyToExclude"],
    (Detail.class) : ["detailPropertyToExclude"]
]

setBlackList(grailsWebDataBinder,blackLists)

...

grailsWebDataBinder.bind(car, new SimpleMapDataBindingSource(params), null, 
         blackLists[car.getClass()] )

PS:作为替代可能设置 grailsWebDataBinder.conversionService...

关于Grails 数据绑定(bind) - 如何排除子属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62687103/

相关文章:

grails - 没有依赖删除的 GORM 关系

grails - 在Grails中编写集成测试以测试数据库持久性

grails - 如何为 Grails 服务运行测试

jenkins - jenkins 构建工作的规则和方法

java - 为什么 Groovy 用 size() 替换 java.lang.String.length()?

groovy - 如何在 Groovy 中减去整数并保留前导零?

json - 将 JSON 数据绑定(bind)到操作参数

javascript - 是否可以让 knockoutjs 更新 'initialdata' 对象?

android - 无法通过 DataBinding 或 Android 扩展访问 View

c# - DataGridView 使用 DataSourceNullValue : enter either nothing, 或 nullValue