当我使用 grailsWebDataBinder
时如何排除子域属性?
例如,我有域:
class Car {
String carPropertyToExclude
Set<Detail> details
static hasMany = [details: Detail]
}
class Detail {
String detailPropertyToExclude
static belongsTo= [car: Car]
}
当我调用 grailsWebDataBinder
的 bind
方法并给 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/