groovy'的例外情况;s可绑定/可否决属性更改侦听器
在两种情况下,通过groovy'的例外情况;s可绑定/可否决属性更改侦听器,groovy,bindable,Groovy,Bindable,在两种情况下,通过@Bindable对绑定groovy属性的赋值不会调用侦听器: (1) 在属性在类本身内赋值的情况下,例如this.prop=newval,或者简单地说,prop=newval (2) 在属性值不变的情况下,obj.prop=oldval 有办法解决这个问题吗?理想情况下,它将支持简单的(.)prop=语法 代码示例: import java.beans.* import groovy.beans.* int changes = 0 def obj = Binding.new
@Bindable
对绑定groovy属性的赋值不会调用侦听器:
(1) 在属性在类本身内赋值的情况下,例如this.prop=newval
,或者简单地说,prop=newval
(2) 在属性值不变的情况下,obj.prop=oldval
有办法解决这个问题吗?理想情况下,它将支持简单的(.)prop=
语法
代码示例:
import java.beans.*
import groovy.beans.*
int changes = 0
def obj = Binding.newInstance()
obj.propertyChange = { changes++ }
obj.prop = "1st change" // change recorded
obj.twoChanges() // no changes recorded
obj.prop = obj.prop // no change recorded
assert changes == 4 // fails: changes is 1
class Binding {
@Bindable String prop
def twoChanges() {
prop = "2nd change"
this.prop = "3rd change"
}
}
For(1)是一个AST,它生成自定义setter,当您访问类内的属性时,它不经过setter。这项工作:
import java.beans.*
import groovy.beans.*
int changes = 0
def obj = Binding.newInstance()
obj.propertyChange = { changes++ }
obj.prop = "1st change" // change recorded
obj.twoChanges() // no changes recorded
obj.prop = obj.prop // no change recorded
assert changes == 3 // fails: changes is 1
class Binding {
@Bindable String prop
def twoChanges() {
setProp( "2nd change" )
this.setProp( "3rd change" )
}
}
对于(2),它似乎是
PropertyChangeListener
,因为属性没有更改。也许你可以提供一个,或者只是创建一个自定义setter。下面是我如何完成的,而不需要使用@Bindable。我愿意接受建议,尤其是这个.with{}
class Obj {
int val = 0
static int numCalls = 0
List assigns = []
void setProperty(String name, Object value) {
this.@"$name" = value
assigns << [name: value]
numCalls ++
}
int nop() {
this.with {
val = val
}
}
int inc() {
this.with {
this.val += 1
}
return this.val
}
}
def obj = Obj.newInstance()
assert obj.val == 0 && Obj.numCalls == 0
assert obj.inc() == 1 && obj.val == 1 && Obj.numCalls == 1
assert obj.nop() == 1 && obj.val == 1 && Obj.numCalls == 2 && obj.assigns.size() == 2
类Obj{
int val=0
静态int numCalls=0
列表分配=[]
void setProperty(字符串名称、对象值){
此。@“$name”=值
通过创建一个隐藏的@Bindable
属性(mprop
),并且只为prop
提供一个getter和setter,而没有一个名为prop
的实际属性,分配,我可以使用您的语法不变。这适用于所有情况,除非属性设置为相同的值(检测到4次更改中的3次):
你能提供一个示例代码吗?(1):我可以在我猜的类中使用[]
s,或者只需要一个set()
并强制所有set都通过它。问题是,在示例中,编写的许多代码都希望直接设置值。(2):这是一个有趣的想法。在这种情况下,属性是原语,我认为这里建议的是自定义类属性,除非我读错了,这是可能的。此时,我正在考虑编写我自己的@Editable
,它将围绕隐藏的数据属性($prop)生成访问器也许吧。@Bindable
代码是公共的吗?我似乎找不到它。我在groovy all jar中找到了正确的实现。我面临着同样的问题。我不太在乎在不更改字段值的情况下触摸字段,但我想强制使用setter,即使是从类内部。你有没有找到比这个更好的解决方案是的。有{}吗?不,我们找不到另一种方法,所以我们解决了这个问题。你看到我1月6日的答案了吗?我用的是这个方法,效果非常好。
import java.beans.*
import groovy.beans.*
int changes = 0
def obj = Binding.newInstance()
obj.propertyChange = { changes++ }
obj.prop = "1st change" // change recorded
obj.twoChanges() // two changes recorded
obj.prop = obj.prop // no change recorded
assert changes == 4 // fails: changes is 3
class Binding {
@Bindable String mprop // changed from prop to mprop
def setProp(x) {setMprop(x)} // new setter
def getProp() {getMprop()} // new getter
def twoChanges() {
prop = "2nd change"
this.prop = "3rd change"
}
}