Take a look at gwt-pectin. I have only looked at the demo and general browsing but it seems quite and functional and achieves many of the objectives you describe.

On 23/01/2010, at 10:28 AM, Jon <jon.ner...@gmail.com> wrote:

Request for comments: Really Simple Binding

IMO UiBinder is a great step forward, but it only solves half the
problem of productive view building - declarative layout. The second
half is binding user interfaces to the model - with as little plumbing
code as possible. Home grown binding frameworks seem to be a dime a
dozen, and it also seems that the GWT team will look at it this year?

Anyway, just wanted to put my ideas out there for comment. Take all
this as unfounded opinion. To me, the number one goal of a binding
framework should be to reduce plumbing code, pure and simple. This is
why all the binding frameworks that require tedious code to bind every
property just suck.

Here's a proposal based on how UiBinder works.

First the binding interface:


/**
* Interface implemented by generated classes that bind user interface
fields to model properties
*
* In general this is two way binding - but only automatic one way
*
* As well as generating the code to move the values back and forth to
the HasValue and HasText interfaces,
* the binder will also generate ValueChangeHandlers for all widgets
that support them to push values back to the model
*
* @param <M> The root class of the model
* @param <O> The class that will own the binder (the view class)
*/
public interface ModelBinder<M, O>
{

   /**
    * Initialises the binding between the model and ui fields, and
pushes the model value to the fields
    *
    * @param model the model to bind to
    * @param owner the owner view
    */
   public void bindAndUpdateFields(M model, O owner);

   /**
    * Pushes the value from a UI field into the model
    *
    * @param field
    */
   public void updateModel(String field);

   /**
    * Pushes all values from the UI to the model
    */
   public void updateModel();

   /**
    * Updates a field with the model value
    *
    * @param field
    */
   public void updateField(String field);

   /**
    * Pushes all model values to the UI
    */
   public void updateFields();
}



This is quite similar to the UiBinder interface and would be used in a
very similar way. Heres an example view, including UiBinder code as
well:


public class ExampleView extends Widget
{

   interface MyUiBinder extends UiBinder<Widget, ExampleView> {}
   private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

interface MyModelBinder extends ModelBinder<MyModel, ExampleView> {}
   private static MyModelBinder modelBinder = GWT.create
(MyModelBinder.class);

   @UiField
@Bind // binds the value of the textbox to a model property with the
same name - M.getName() - DRY
   TextBox name;

   @UiField
   @Bind("foo.bar") // binds the value to the M.getFoo().getBar()
property
@BindConverter(SomeConverer.class) // provide a class to convert for
values back and forth - should be automatically supplied for
primatives and Dates
   TextBox nameTextBox;

   @UiField
@Bind("x.y.z") // binds the selected value to M.getX().getY ().getZ() @BindList("list()") // gets the list of values for the list box from
M.list()
   ListBox listbox;

   public ExampleView()
   {
       uiBinder.createAndBindUi(this);
       modelBinder.bindAndUpdateFields( getModel(), this );
   }

   public MyModel getModel()
   {
       return model;
   }
}


The segments in the expression language would generate calls to a
property, field, method, Map or JSONObject in that order, depending on
what the generator finds on the M class as it traverses the
expression.
Obviously the last segment has to generate set() calls as well as get
().
This could all be checked at compile time (and in the Eclipse plugin?)
the same way that the CSSResource value() function works.

Various widgets would need special treatment in the generator - such
as ListBox. Woudl be a good oportunity to standardise how list based
widgets work in the same way that HasValue, HasText & HasHTML
standardise the simple widgets.

As mentioned above, changes to the values in the UI would
automatically be pushed to the model by automagically hooking up
ValueChangeHandlers. Changes to the model will need to be manually
pushed to the UI through the updateField() or updateFields() methods.

Things that need further thought:
1. Converters
2. Validation
3. Cut out the middleman - allow the model binding to be specified in
a UiBinder xml file without needing a UiField eg
<g:TextBox bind="foo.bar" />
This would probably mean that ModelBinder and UiBinder need to know
about each other.

Thoughts?

Cheers,

Jon Nermut

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to