2014-04-08 13 views
1
@Bindable를 통해 바인딩 끝내 속성에 할당 청취자를 호출하지 않는 경우 두 가지 상황이 있다는 것을 나타납니다

:예외가의 그루비하는 바인딩/거부 프로퍼티 변경 청취자

(1) 속성 내에서 지정되는 경우 단순히 this.prop = newval, 또는, 같은 클래스 자체,

(2) 경우에 속성의 값이 변경되지 않습니다 obj.prop = oldval

prop = newval이 주위에 방법이 있나요? 이상적으로는 간단한 (.)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" 
    } 
} 
+0

예제 코드를 제공 할 수 있습니까? – Opal

답변

2

, 나는 당신의 구문이 변경 사용 할 수 있었다. 이 속성이 동일한 값으로 설정된 경우를 제외하고 모두 작동합니다 (4 개의 변경 중 3 개가 감지 됨).

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" 
    } 
} 
1

(1), @Bindable 다른 물건, 사용자 정의 세터들 사이에서, 생성하는 AST가, 그리고 당신은 클래스 내부 속성에 액세스 할 때, 그것은을 통과하지 않습니다 세터. 이 작품 : 속성이을 변경하지 이후 들어

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), 음, PropertyChangeListenerstandard behavior 것 같다. 어쩌면 custom object, with a custom equals을 제공하거나 맞춤 설정기를 만들 수 있습니다.

+0

(1) : 내가 생각하는 클래스 내에서'[]'s를 사용하거나'set()'을 가지고 모든 세트를 강제로 통과시킬 수 있습니다. 여기에 나와있는 코드의 상당수는 예제에서 값을 직접 설정하려고합니다. (2) : 그것은 흥미로운 아이디어입니다. 이 경우 프로퍼티는 프리미티브 (primitive)이며, 나는 그것이 틀린 것을 읽지 않는 한 사용자 정의 클래스 프로퍼티라고 제안한다. 이 시점에서 숨겨진 데이터 속성 ($ prop) 주위에 접근자를 생성하는 내 자신의'@ Editable '을 작성하려고 생각합니다. '@ Bindable '코드는 공개되어 있습니까? 나는 그것을 찾을 수 없을 것 같았다. – inyourcorner

+0

groovy-all jar에서 구현을 발견했습니다. – inyourcorner

0

다음은 @Bindable을 사용할 필요없이 끝내는 방법입니다. 나는 특히, this.with {} 제안에 열려 있습니다. 숨겨진 @Bindable 특성 (mprop)를 생성하고 prop라는 이름의 실제 재산없이 prop에 대해서만 getter와 setter를 제공함으로써

class Obj { 
    int val = 0 
    static int numCalls = 0 
    List assigns = [] 

    void setProperty(String name, Object value) { 
    [email protected]"$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 
+0

나는 똑같은 문제에 직면 해있다. 값을 변경하지 않고 필드를 만지는 것에 너무 신경 쓰지는 않지만 클래스 내부에서라도 세터의 사용을 강요하고 싶습니다. {}와 함께이 솔루션보다 나은 솔루션을 찾았습니까? – greymatter

+0

아니요, 우리는 다른 방법을 찾을 수 없었으므로 그 문제를 해결했습니다. – inyourcorner

+0

1 월 6 일 내 대답을 보았습니까? 이 방법을 사용하고 있으며 완벽하게 작동합니다. – greymatter