Models are very simple in nature. Their responsibility is to hold data that can be used by both Controller and View to communicate with each other. In other words, Models are not equivalent to domain classes.Models can be observable by means of the @Bindable AST Transformation. This actually simplifies setting up bindings so that changes in the UI can automatically be sent to model properties and vice versa.@Bindable will inject a java.beans.PropertyChangeSupport
field and all methods required to make the model an observable class. It will also make sure that a PropertyChangeEvent
is fired for each observable property whenever said property changes value.The following is a list of all methods added by @Bindable
void addPropertyChangeListener(PropertyChangeListener listener)
void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)
void removePropertyChangeListener(PropertyChangeListener listener)
void removePropertyChangeListener(String propertyName, PropertyChangeListener listener)
PropertyChangeListener[] getPropertyChangeListeners()
PropertyChangeListener[] getPropertyChangeListeners(String propertyName)
void firePropertyChange(String propertyName, Object oldValue, Object newValue)
The following is a list of all methods added by @Vetoable
void addVetoableChangeListener(VetoableChangeListener listener)
void addVetoableChangeListener(String propertyName, VetoableChangeListener listener)
void removeVetoableChangeListener(VetoableChangeListener listener)
void removeVetoableChangeListener(String propertyName, VetoableChangeListener listener)
VetoableChangeListener[] getVetoableChangeListeners()
VetoableChangeListener[] getVetoableChangeListeners(String propertyName)
void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
Another annotation, @Listener, helps you register PropertyChangeListeners
without so much effort. The following codeimport griffon.transform.PropertyListener
import groovy.beans.Bindable@PropertyListener(snoopAll)
class MyModel {
def controller
@Bindable String name @Bindable
@PropertyListener({controller.someAction(it)})
String lastname def snoopAll = { evt -> … }
}
is equivalent to this oneimport groovy.beans.Bindable
import java.beans.PropertyChangeListenerclass MyModel {
def controller
@Bindable String name
@Bindable String lastname def snoopAll = { evt -> … } MyModel() {
addPropertyChangeListener(snoopAll as PropertyChangeListener)
addPropertyChangeListener('lastname', {
controller.someAction(it)
} as PropertyChangeListener)
}
}
@PropertyListener accepts the following values
- in-place definition of a closure
- reference of a closure property defined in the same class
- a List of any of the previous two