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
|