Request for comments: Really Simple Binding

8 views
Skip to first unread message

Jon

unread,
Jan 22, 2010, 6:28:12 PM1/22/10
to Google Web Toolkit Contributors
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

Miroslav Pokorny

unread,
Jan 22, 2010, 10:59:01 PM1/22/10
to google-web-tool...@googlegroups.com, Google Web Toolkit Contributors
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.

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

Jon

unread,
Jan 22, 2010, 11:41:28 PM1/22/10
to Google Web Toolkit Contributors
Pectin is one of the code based bind frameworks I want to avoid.
Despite some nice syntax, you still have to write code like this:

binder.bind(model.givenName).to(givenNameField);
binder.bind(model.surname).to(surnameField);
binder.bind(model.age).to(age);

IMHO binding has to be declarative to be of value.

Btw heres a list of some of the amazing proliferation of gwt
frameworks that do some sort of data binding. It shows the pressing
need to have this in GWT.
However theres not many in this list with enough substance and back
that I'd use them on an enterprise project - binding needs to be in
GWT. Also not many are designed for use with UiBinder.

http://code.google.com/p/gwt-pectin/
http://code.google.com/p/gwt-beans-binding/
http://code.google.com/p/acris/
http://code.google.com/p/gwt-beans/
http://code.google.com/p/gwt-data-binding/
http://code.google.com/p/gwt-ent/
http://code.google.com/p/uface/
http://code.google.com/p/gwittir/
http://code.google.com/p/glue4gwt/
http://code.google.com/p/gwtxp/
http://code.google.com/p/gwtoolbox/
http://code.google.com/p/kiyaa/
http://code.google.com/p/crux-framework/
http://code.google.com/p/gwt-model/
http://code.google.com/p/smartgwt/
http://www.extjs.com/products/gxt/
http://code.google.com/p/gwt-xtender/
http://code.google.com/p/gwt-pojo-forms/
http://code.google.com/p/lotura/
http://code.google.com/p/gwtbinding/
http://code.google.com/p/enwelib/
http://code.google.com/p/zenbinding/
http://code.google.com/p/gyraf/
http://code.google.com/p/gwt-validation/
http://code.google.com/p/gwt-hibernate/

and I'm sure there's more!

On Jan 23, 2:59 pm, Miroslav Pokorny <miroslav.poko...@gmail.com>
wrote:


> 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.
>

Miroslav Pokorny

unread,
Jan 22, 2010, 11:52:26 PM1/22/10
to google-web-tool...@googlegroups.com, Google Web Toolkit Contributors
I can't comment if this already available but it should not be a
problem to create annotations that express the binder building
expresseions you quoted. Many of the libs you mention are incomplete
examples of some of your objectives.

Once one declared bindings declaratively ( using annotation ???) what
s wrong with pectin? It does binding validation and it appears to work
just fine and appears extensible.

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

Jon

unread,
Jan 24, 2010, 12:23:26 AM1/24/10
to Google Web Toolkit Contributors
The biggest problem with pectin, besides its verbosity, is that it
appears to be run by a single committer, which is too big a risk to
include in an big development project.
UiBinder isnt the best solution to declarative UI with GWT (Crux and
Kiyaa are arguably better) - but its now the standard and supported by
the GWT Team. You can guarantee that if you use it, it will stick
around and there will be an upgrade path.
The same needs to have with data Binding - it needs to be in the core
of GWT so that you can invest in writing the code without the risk of
having a dead project on your hands.

On Jan 23, 3:52 pm, Miroslav Pokorny <miroslav.poko...@gmail.com>
wrote:


> I can't comment if this already available but it should not be a  
> problem to create annotations that express the binder building  
> expresseions you quoted. Many of the libs you mention are incomplete  
> examples of some of your objectives.
>
> Once one declared bindings declaratively ( using annotation ???) what  
> s wrong with pectin? It does binding validation and it appears to work  
> just fine and appears extensible.
>

Andrew Pietsch

unread,
Jan 26, 2010, 4:18:55 PM1/26/10
to Google Web Toolkit Contributors
I guess verbosity is somewhat in the eye of the beholder -I would have
thought that watermark(myField).withValueOf(anotherField) was pretty
concise for a dynamic watermark (c;

Pectin came out of developing large scale Swing applications with
highly demanding UX/UI requirements (in the banking sector). Creating
a bespoke value model solution allowed us to create highly functional
forms with very little code in a very consistent manner. The
disadvantage that it was specific that that app - think obfuscated
fields that become editable on supervisor override, automatic focus
transfer on validate data entry etc - hardly an everyday requirement.
We would have used SpringRichClient or JGoodies Binding but they
didn't provide good extension points at the time. This is why I wrote
pectin - I wanted a value model style binding framework that I could
extend as required.

Granted though, for simply putting a bean on a form it can look like a
bit of overkill. But in my experience the UX/UI guys rarely want
simple beans on forms.

Pectin does lack hooks into a UiBinder style template system. I'd
welcome any contributions in this area if you're interested.

Cheers
Andrew

Reply all
Reply to author
Forward
0 new messages