@Observable
The @Observable
annotation simplifies writing observable properties.
The simplest use-case involves annotating one of a standard getter/setter pair with the annotation.
For example:
@ArezComponent
public abstract class MyModel
{
private int _value;
@Observable
public int getValue()
{
return _value;
}
public void setValue( final int value )
{
_value = value;
}
}
The component can also be defined using a pair of abstract getters and setters, in which case the annotation processor will provide a suitable implementation of the getter. This often results in shorter, simpler code. For example:
@ArezComponent
public abstract class MyModel
{
@Observable
public abstract int getValue();
public abstract void setValue( int value );
}
There are additional constraints that are apply when defining observable. i.e. The type of the getter and setter
must match. These constraints are detailed in the @Observable
API documentation.
Customizing names
The @Observable
annotation methods can be named using non-standard naming conventions and this is sometimes
required to integrate with existing frameworks. In this scenario, the user must add and additional parameter
to the annotation to explicitly name the observable property. This may require annotating both the setter and
the setter with the @Observable
annotation.
For example:
@ArezComponent
public abstract class Currency
{
private BigDecimal _amount;
@Observable( name = "amount" )
public BigDecimal amount()
{
return _amount;
}
@Observable( name = "amount" )
public void updateAmount( final BigDecimal amount )
{
_amount = Objects.requireNonNull( amount );
}
...
}
Custom change propagation
Sometimes you want to integrate Arez into systems that have existing change propagation mechanisms. For
example, Arez was integrated in a java variant of React called React4j. React4j
components are configured by passing the component props
. These components can be re-configured by passing
the component another value for props
. The react framework is wholly responsible for detecting changes in
props
, assigning the props
field and then invoking a callback method on the component to notify the
component that props
has changed. Making this props
property observable within Arez involved the following
changes.
- Disabling the
@Observable
setter via the@Observable.expectSetter
parameter on the getter. - Accessing the underlying
ObservableValue
primitive using the@ObservableValueRef
annotation. See accessing primitives documentation on details on how this is achieved. - Manually invoking
ObservableValue.reportChanged()
in the callback.
For example:
@ArezComponent
public abstract class ReactComponent
{
@Observable( expectSetter = false )
Props props()
{
//Return the native props object here.
...
}
//This will be overridden and implemented in the Arez subclass
@ObservableValueRef
abstract ObservableValue<Props> getPropsObservableValue();
// This method is wrapped in an Action to ensure change is propagated
// correctly in arez system.
@Action
void reportPropsChanged()
{
getPropsObservableValue().reportChanged();
}
// This method is invoked by the React runtime
void componentWillReceiveProps( @Nonnull final Props nextProps )
{
reportPropsChanged();
...
}
...
}