Binding properties of nested collections

21 views
Skip to first unread message

Tibi

unread,
May 18, 2010, 7:13:34 AM5/18/10
to GWT Pectin
After investigating several solutions of this field we picked gwt-
pectin as far the most type-safe library. Well done!

However we wonder how to solve the following problem. We use forms
with embedded list of beans that have further embedded beans. These
beans are displayed in the screen as embedded vertical list panels
with several bound controls. How can we bind properties of these
embedded list of beans?

e.g.
class Contract {
String Partner;
Date date;
List<ContractItem> items;
}

class ContractItem {
int amount;
List<PaymentConditions> paymentConditions;
}

class PaymentCondition {

}

I understand nested beans can be bound by setting the bean source
property, however I couldn't figure out how to provide properties of
beans in nested collections.

TIA

Andrew

unread,
May 19, 2010, 12:49:55 AM5/19/10
to GWT Pectin
Howdy,

It's hard to give specific advice without more detail, but for now
there's no direct out of the box way to bind multiple nested
collections (i.e. tree like structures). In this case I generally use
nested editors each with their own model. For example, if your
contract item list is editable (i.e. the user can add and remove
items) then you could use `AbstractDynamicList` to create a
`ContractItemsListEditor` to bind to `Contract.items`. This editor
then implements the `createEditor()` method to return a suitable
`HasValue<ContractItem>` widget. This widget would have it's own
model and could use a similar approach for the
`ContractItem.paymentConditions`. If you need to do validate/commit
then you'd need to implement this at the editor level (but each editor
would delegate to their respective models).

The demo uses this widget in various places, see favorite cheeses
widget in
http://code.google.com/p/gwt-pectin/source/browse/trunk/demo/src/main/java/com/pietschy/gwt/pectin/demo/client/basic/BasicForm.java,
in this case it's just creating a list of HasValue<String> editors.

Please also note that AbstractDynamicList is still pretty primative
and needs some work to get it to production level (no i18n etc) but
feel free to use it as a starting point if it suits.

I've also had the case where I'm binding a fixed list of complex
editors from a ListModel (in the vertical panel style). In this case
I've done it manually by using an IncrementalUiCommand in conjunction
with a `editor factory` to build the UI whenever the list changes (to
avoid slow script warnings). In this case FormModel's are overkill
and I've manually bound to ValueModels and ListModels directly. I
hope to add support for binding plain ValueModels and ListModels to
HasValue<T> widgets etc in the not to distant future.

The next version of Pectin will also support binding to nested beans
using basic property paths (e.g.
fieldOfType(String.class).boundTo(provider, "a.b.c");) but
unfortunately this won't help in this case.

Hope this helps.
Cheers

Tibi

unread,
Jun 3, 2010, 11:15:53 AM6/3/10
to GWT Pectin
Dear Andrew,

thanks, we have chosen the AbstractDynamicList solution. Unfortunately
this way we separate the model into various files, but we can live
with that for the moment.

Tibor

hbf

unread,
Jul 2, 2010, 12:22:02 PM7/2/10
to GWT Pectin
On May 19, 6:49 am, Andrew <andrew.piet...@gmail.com> wrote:
> Howdy,
>
> It's hard to give specific advice without more detail, but for now
> there's no direct out of the box way to bind multiple nested
> collections (i.e. tree like structures).  In this case I generally use
> nested editors each with their own model.

Can you please explain how you use a model for each nested item? I
understand that I'd have to do something like this:

items = new AbstractDynamicList<ContractItem>("Add item")
{
@Override
protected HasValue<ContractItem> createWidget()
{
return new ContractItemWidget();
}
};

but where does the new model come in?

Thanks,
Kaspar

Andrew

unread,
Jul 5, 2010, 8:33:17 PM7/5/10
to GWT Pectin
Hi Kaspar,

My advice to try AbstractDynamicList may have been misguided in your
case, but I'll answer the initial question as to where does the
additional model go here just for completeness. Pectin's current
notion of a form is definitely constrained to to basic forms with
fields and simple lists, so once widgets become more complex (i.e.
subforms with their own validation requirements etc) a single form
model no longer works. I tend to find there are many other issues
once forms become more complex (such as requiring the use of
incremental commands to build the UI, which introduces async &
concurrency issues etc) so a basic model ceases to be adequate.

Anyway, my initial thoughts in your case were to solve the problem
using nested editors each with their own FormModel. AbstractDynamic
list would be the glue that mapped the list of contract items to each
contract item editor. I'm assuming you need validation in your
example so would probably subclass AbstractDynamicList to delegate
this to each editor. There's not controller in all of this, it's more
a decorate/delegate approach and may not be to your liking. This
would be more testable if AbstractDynamicList took somthing like a
Provider<ContractItemWidget> as a widget factory instead of using a
factory method. That way you could mock much easier and check that
the delgations all work. I'm talking off the top of my head here, you
may have a more vigorous testing approach than me so this may not work
for you.

public class ContractItemListWidget extends
AbstractDynamicList<ContractItem>
{
public ContractItemListWidget()
{
super("Add item");
}

@Override
protected HasValue<ContractItem> createWidget()
{
return new ContractItemWidget();
}

public boolean validate()
{
boolean valid = true;
// iterating over the widgets currently sucks
for (each ContractItemWidget)
{
if (!contractItemWidget.validate())
{
valid = false;
}
}

return valid;
}

public void commit()
{
// iterating over the widgets currently sucks
for (each ContractItemWidget)
{
contractItemWidget.commit();
}
}
};

public class ContractItemWidget extends Composite implements
HasValue<ContractItem>
{
// here's the model for the contract item subform
ContractItemFormModel model = new ContractItemFormModel();
FormBinder binder = new FormBinder();

public ContractItemWidget()
{
// build the view and do the binding etc.
}

public void setValue(ContractItem item, boolean fireEvents)
{
// This method will be called automatically by
AbstractDynamicList when
// ever it's ListModel<ContractItem> changes
// update the model and the view will follow...
model.setBean(item);

if (fireEvents) { ... }
}

public boolean validate() {
return model.validate();
}

public void commit() {
model.commit();
}
}

I've been slowly building some controllers along the lines of what
Apple use in their key/value coding guidelines (very early days and
still far to embarrasing to release publicly (c;). But if I were
going down that route I'd probably try doing something like the
following.

public ContractListController
{
private MutableListModel<ContractItem> items;

public ContractListController(MutableListModel<ContractItem> items)
{
this.items = items;
this.items.addListModelHandler(new ListModelChangedHandler()
{
protected void onListDataChanged(ListModelChangedEvent event)
{
rebuildView();
}
}
}

protected void rebuildView()
{
// do the hard work, possibly with an incremental command if
it's
// going to take a long time...
}

public void go(HasWidgets container)
{
// install my view in the container.
}

public boolean validate()
{
boolean valid = true;
for (each ContractItemWidget)
{
if (!contractItemWidget.validate())
{
valid = false;
}
}

return valid;
}

public void commit()
{
for (each ContractItemWidget)
{
contractItemWidget.commit();
}
}
}

This is extremely similar to the AbstractDynamicList approach above
(but is more work as you'd have to manage the add/remove stuff
yourself), but to me it's probably a better as you can create abstract
controllers that can be reused in many different views scenarios (i.e.
the controller would take a Provider<Editor<T>> where Editor<T> has
the methods validate(), commit(), dirty() etc.) It would be also
easier to add things like a plugable ViewBuilderStrategy that could
use incremental commands to build complex views. The controller can
also publish additional state (such as busyBuilding(), dirty() etc)
that the ContractEditorController can use if it needs (e.g. to
intercept widow close events and prompt for closing etc).

With an appropriate controller heirarchy the above example would could
possibly be simplified to something like:

// inside my main controller..
contractItemListController = new
ListController<Editor<ContractItem>>(MutableListModel<ContractItem>
itesm, Provider<Editor<ContractItem>> editorFactory);

contractItemListController.go(myContainer);

Anyway, I'm not sure if this is helpful or not or if it would work in
your case. I haven't settled on a "pectin way" in these sort of
situations, I'm still experimenting in my own code so all my advice
contains at least some level of arm waving (c: If you find another
way that you prefer I'd be interested to know your thoughts.

And finally, would you be happy for me to post this reply on the
discussion group?

Cheers

hbf

unread,
Jul 6, 2010, 3:52:35 AM7/6/10
to GWT Pectin
Hi Andrew,

I have followed your advice and your suggestions work. So thanks a lot
for your feedback, which was very useful.

After looking at your solution, it seems to me that in the "UI
Commands & Buttons" example of

http://scratchpad.pietschy.com/pectin/PectinDemo.html

you could not easily add validation because again, the
AbstractDynamicList for the cheeses does not support "out-of-the-box"
the validate() and confirm() methods for its text boxes. It is the
same problem as in our Contract example. Correct?

So it seems that even for "simple" forms we need some notion of
"nested" widgets. In your approach so far, views (TextBox'es,
CheckBox'es, etc.) just have values and don't know about models.
However, the view AbstractDynamicList suddenly needs to know about the
models of its subwidgets...

Is there an easy fix for this? Or do you intend to go a completely
different path like the Cocoa-style controllers you mentioned, which
is MVC IIUC?

Best,
Kaspar

hbf

unread,
Jul 6, 2010, 4:07:14 AM7/6/10
to GWT Pectin
Hi Andrew,

As a side remark: As you state on the project website, Pectin is not a
general binding solution. Do you know of a framework for GWT that
accomplishes this in a simple manner, including support for reusable
and nestable widgets? I was very much impressed by the expressiveness
of your library (the "when(...)" syntax, etc.) and so far could not
find anything that suits my purpose, let alone be as elegant with
respect to expressiveness.

Maybe gwittir is coming close? I am looking into it right now. I do
not know a lot about MVP (the P in it) and thus cannot say right now
whether something like gwt-platform will help me?

After a first glimpse at the documentation of the latter, I get the
feeling that (i) gwt-platform would introduce a lot of complexity I
don't need for my project and (ii) does not provide simple meachnisms
for forms (validateField().using(...), enable().when(), etc.). (Please
correct me if I am wrong.)

Best,
Kaspar

On Jul 6, 2:33 am, Andrew <andrew.piet...@gmail.com> wrote:

Andrew

unread,
Jul 6, 2010, 10:22:46 PM7/6/10
to GWT Pectin
Howdy,

> I have followed your advice and your suggestions work. So thanks a lot
> for your feedback, which was very useful.

Glad it helped.

> After looking at your solution, it seems to me that in the "UI
> Commands & Buttons" example of
>
> http://scratchpad.pietschy.com/pectin/PectinDemo.html
>
> you could not easily add validation because again, the
> AbstractDynamicList for the cheeses does not support "out-of-the-box"
> the validate() and confirm() methods for its text boxes. It is the
> same problem as in our Contract example. Correct?

It has a problem but it's not quite that one in this case... In the
demo the validate/commit methods aren't needed since the values are
simple strings and can be validated in the FormModel (using a
ListValidator). The demo's problem is the messages generated
validator won't be automatically displayed by the widgets. To
overcome this in other projects I've made my AbstractDyamicList
implement ListValidationDisplay and had it delegate to to each item
editor that in turn implements ValidationDisplay, then the bindings
automatically wire them up.

The validate/commit problem arises when the list item requires a
compound editor (since putting something like a ListValidator<Address>
on the main FormModel would become unweildy.. i.e. it would be
difficult/ugly to associate a "please enter a postcode" message in the
FormModel with a particular widget in the AddressEditor component).

> So it seems that even for "simple" forms we need some notion of
> "nested" widgets. In your approach so far, views (TextBox'es,
> CheckBox'es, etc.) just have values and don't know about models.
> However, the view AbstractDynamicList suddenly needs to know about the
> models of its subwidgets...

Yep, there's a definite a break once you need to start nesting. I
think in there a 4 different cases to consider:

1. Non-compound values that map directly to simple widgets
2. Lists of non-compound values that map to a list of simple
widgets
3. Compound values bound to a compound editor
4. List of compound values bound to a list of complex editors.

Of these 1 is the current standard pectin usage, 2 is what
AbstractDynamicList was originally built to solve (but needs
improvement). 3 & 4 aren't as straight forward. In the past I'd
approached 3 from the perspective of using reusable Widgets and
models, i.e. an AddressEditor and AddressModel being used something
like addressEditor.setModel(personModel.addressModel) although it's
not as clean as I'd like from a binding perspective. 4 is more
difficult again since the layout and presentation of the "list of
editors" is almost always going to be so application specific.

> Is there an easy fix for this? Or do you intend to go a completely
> different path like the Cocoa-style controllers you mentioned, which
> is MVC IIUC?

I don't have an absolute opinion, but I think:
1. Nested controllers are the most flexible and generalised
approach.
2. An improved AbstractDynamicList that has out of the box support
for validation in case 2 above would be worth while.
3. There's probably some gray area between the basic approaches of 1
& 2. i.e. nested/specialised widgets vs full blown controllers.

As far as I can see if we try and avoid controllers then we're heading
down the one-model-to-rule-them-all path, and given the generally
demanding and varied requirements of UIs I can't see this working at
all. Using controllers lets you layer the design and break it into
managable pieces. I.e. form models deal with the details of how the
low level widgets behave, the controller works at the next layer up to
mediate between the various bits and to handle higher level things
like validate/commit cycles etc. It can expose state appropriate for
the controllers role such as hasUnsavedChanges, selection etc. A
master controller can then make decisions based on the state of it's
child controllers, models and components etc. For example I have a
contoller in my current app that has a child SelectionController<T>
and EditorController<T>. The SelectionController exposes an
InterceptedValueModel<T> for the selection. The master controller
intercepts selection changes and if the EditorController is dirty
prompts to save/cancel otherwise it allows the selection to proceed
and the EditorController is updated via a binding. e.g.

// During initialisaiton we:
// 1. add an interceptor for selection changes.
selectionController.selection().interceptUsing(unsavedChangesInterceptor);
// 2. bind the selection to our editor controller
Binder.bind(selectionController.selection()).to(editorController));

The editorController can split T into various Value/ListModels as
required. It could bind controllers to these models or have it's own
FormModel or both. There's still a fair bit to think of in the above
example though, i.e. the item update event (after saving) would need
to propegate to both the selection controller and the
editorController. I'm halfway through cleaning this up in my current
app and will likely go down the path where the master controller owns
the selection ListModel<T> & selection ValueModel<T> and passes them
to the controllers as requried.

I'm also reluctant to use the term MVC since now days there are so
many different variations to choose from that it has become somewhat
meaningless unless you explain exactly how you're implementing the
various bits, i.e. I have models, views and controllers, my models are
almost always observable, my controllers typically have commands,
models (either FormModels or simple Value/ListModels) and possibly
other controllers. The controllers mediate between the various bits,
commands (often) operate on the models (or interfaces models then
implement), contollers (often) intercept commands. Commands usually
model their own state (enabled, text etc). I aim to have passive
views (which are generally passed the the models and commands and
simply bind the models and commands to widgets). So from that
perspective I'm not really sure how it fits into popular understanding
of the MVC concept. It's certainly a different implementation from
the MVC I learnt from Swing, but as I see it this is because the
problem/context is different; I'm building an app, and the Swing
engineers were building a widget toolset.

Anyway, I've prattled on for ages... hope at least some of that helped
you decide what approach might work for you.

Cheers
Andrew

Andrew

unread,
Jul 6, 2010, 11:37:10 PM7/6/10
to GWT Pectin
Howdy,

> As a side remark: As you state on the project website, Pectin is not a
> general binding solution. Do you know of a framework for GWT that
> accomplishes this in a simple manner, including support for reusable
> and nestable widgets? I was very much impressed by the expressiveness
> of your library (the "when(...)" syntax, etc.) and so far could not
> find anything that suits my purpose, let alone be as elegant with
> respect to expressiveness.

Pectin has been expanding beyond forms to become a set of more basic
components such as Value/ListModels, Commands, Interceptors etc that
can be used outside of FormModels. In the last post I mentioned about
the approach I'm currently taking with controllers so hopefully that
gives you an overview of how I'm using it so you can compare that with
other techniques.

> Maybe gwittir is coming close? I am looking into it right now. I do
> not know a lot about MVP (the P in it) and thus cannot say right now
> whether something like gwt-platform will help me?
>
> After a first glimpse at the documentation of the latter, I get the
> feeling that (i) gwt-platform would introduce a lot of complexity I
> don't need for my project and (ii) does not provide simple meachnisms
> for forms (validateField().using(...), enable().when(), etc.). (Please
> correct me if I am wrong.)

I can't really offer advice for libraries I haven't used on a project
I haven't seen (c: Well I could... but it would either be unreliable
or I'd have to take some time and charge a fee (c: Both libraries
look pretty comprehensive though and gwitter has a much broader scope
than pectin (but as you noted with a different style to binding). Gwt-
platform also looks pretty nice, but there's some work on Activities/
Places in GWT 2.1 that might be worth looking at as well. GWT 2.1
will also have RequestFactory/ValueStore/EditorBinding features you
might find worth checking out.

Hope this helps
Cheers
Andrew
Reply all
Reply to author
Forward
0 new messages