Bindings in generalThis document is a specification draft for Tweed 0.2.0. Current version does not implement the same level of features. A Binding is the set of operations required to update a View from a Model, or a Model from a View. A Model is an object containing parameters required for server-side processings. A View is a graphical object that is a part of the GUI. Most of time, bindings mean a 1-1 relationship between Model's properties and View's widgets. Bindings are applied just before / after invoking a Command on the server:
Every time bindings are applied, incorrect user input may be detected. The user receives a description of the validation failure, which should include, as possible, a reference to the Widget(s) containing incorrect / inconsistent values. Creating a View
Let's define a View object. It is named
public class MyView1 extends ... {
/*package*/ widget1 = new JTextField() ;
/*package*/ widget2 = new JTextField() ;
/*package*/ widget3 = new JSpecialWidget() ;
}
Please note that all widgets involved in Bindings have a package-private scope. Creating a Model
Now let's define a Model object. It is named
public interface MyModel1 extends Model {
int getValue1() ;
void setValue1( int value1 ) ;
String getValue2() ;
void setValue2( String value2 ) ;
Date getValue3() ;
void setValue3( Date value3 ) ;
}
A Model object is an interface, which extends
Creating an automatic Binding
Let's define a Binding between a
This basic case is very simple to implement. We just need to:
public class MyBinding0 extends Binding {
private final Model1 myModel ;
private final View1 myView ;
public class MyBinding1( Context context, Model1 myModel, View1 myView ) {
super( context ) ;
this.myModel = myModel ;
this.myView = myView ;
}
protected void define() {
attach( myModel.getValue1(), myView.widget1 ) ;
attach( myModel.getValue2(), myView.widget2 ) ;
}
}
This minimal Binding will work, because Tweed knows how to deal
with
If we want more accurate validation failure messages, we just have
to add a parameter to the
attach(
myModel.getValue1(),
myView.widget1,
"Something wrong with widget 1"
) ;
Creating a custom Binding
Now we can imagine situations where automatic Bindings are not
enought. For example,
Let's redefine
public void viewToModel() {
super() ; // applies automatic bindings
if( myView.widget3.isValid() ) {
myModel.setProperty3( myView.widget3.getValue() ) ;
} else {
createMessage( "Widget 3 contains something invalid" ).
addComponent( myView.widget3 ) ;
}
}
In the example above, we know that user input was wrong with
Now let's redefine
public void modelToView() {
super() ; // applies automatic bindings
try {
myView.widget3.setValue( myModel.getProperty3() ) ;
} catch( ValidationException ex ) {
createMessage( "Something wrong with widget 3" ).
addComponent( myView.widget3 ) ;
}
}
In the example above, we catch a
Creating hierarchical Bindings
Bindings can be reused and chained hierachically. Let's imagine
that
public class MyView0 extends ... {
// Some other widgets here...
/*package*/ nestedView = new MyView1() ;
}
public interface MyModel0 extends Model {
// Some other properties here...
MyModel1 getMyModel1() ;
void setMyModel1( MyModel1 myModel1 ) ;
}
We can reuse the
public class MyBinding0 extends Binding {
private final Model0 model0 ;
private final View0 view0 ;
public class MyBinding0( Context context, Model0 model0, View0 view0 ) {
super( context ) ;
this.model0 = model0 ;
this.view0 = view0 ;
}
protected void define() {
// Some other attachments here...
new MyBinding1(
this,
model0.getMyModel1(),
view0.nestedView
) ;
}
}
Passing the instance of
public MyBinding1( Binding parent, Model1 myModel, View1 myView ) {
super( parent ) ;
this.myModel = myModel ;
this.myView = myView ;
}
Instantiating a ModelOnly the interface defining Model's property needs to be specified. The implementation is built "magically" by a Factory, and acts like a "stupid" bean just able to keep values. MyModel1 model = ( MyModel1 )
getContext().getModelFactory().create( MyModel1.class ) ;
This requires to have access to a valid
Invalidating Model's propertiesServer-side Command implementations perform validations on Models. When one or more Model's properties are involved in a validation failure, they can be tagged as "dirty". makeModelDirty( "The message" ).
addProperty( myModel.getProperty1() ).
addProperty( myModel.getProperty2() )
;
The code above is supposed to appear in a concrete Command
implementation. The
Implementation notes
It seems that
|