Hi Ray,

On Wed, Oct 8, 2008 at 6:24 PM, Ray Cromwell <[EMAIL PROTECTED]> wrote:
>  Something struck me about the way you are approaching things, that
> is, letting the BoundField's return widgets. With the new HasData
> stuff being proposed, why not let the programmer create the widget,
> and bind the field to an already created widget? (if the widgets
> export an interface like HasData which permits wiring them up.) That
> seems to provide more flexibility, since people tend to design the
> look and layout of the widgets and wire up the logic separately.
>
> Couldn't the API look more like this?
>
> PersonForm form = GWT.create(PersonForm.class);
>
> form.getFirstName().bind(existingWidget, personInstance);
> form.getLastName().bind(anotherExistingWidget, personInstance);
>
> or perhaps
>
> form.bindInstance(personInstance).
>  getFirstName().bind(widget1).
>  getLastName().bind(widget2);
>
> I realize there may be issues making this work with arbitrary
> subclasses of Widget, but let's leave that aside for a moment and
> assume the proper support can be added to the widgets.  This would
> also seem to work alot better with the proposed UI Templating system
> being proposed.

Sorry for the long delay--it's taking a while to come back to the real
world after a weekend that included about 45 hours in a car and a fair
amount of turkey.

Anyway, I've thought some more about your suggestion here (that
widgets be passed into the binding framework, rather than defining
them on the form), and I think I agree with you.  Given that the same
value could be displayed/edited in more than one kind of widget, the
choice of _which_ widget seems like a presentation issue while the
business logic in the binding itself seems like a model issue.  I
think that's enough argument for me that you're right.  (As a bonus,
your suggestion also cleans up the smell of defining constructor
arguments in string form on the @UseEditor and @UseViewer
annotations.)

I do disagree with the particular APIs you suggested, though.  To me,
a Form is to a class as a BoundForm is to an instance.  I think it
should be possible to use the same form in multiple places at once,
and each "place" should be relatively independent, sharing only
definitions and not "instances".  I'd therefore suggest something like
the following:

BeanForm form = GWT.create(BeanForm.class);

BoundForm<BeanType> boundForm = form.bindTo(beanInstance);

panel.add(boundForm.bind(form.getFieldOne(), new
TextBoxEditor(CurrencyConverter.INSTANCE));
panel.add(boundForm.bind(form.getFieldTwo(), new
LabelViewer(DefaultToString.INSTANCE));
panel.add(boundForm.bind(form.getFieldThree(), new CreditCardEditor());

The above code could be shortened if you assume it was in the context
of a DataComposite<BeanType> instead of in some random UI code:

public class BeanComposite extends DataComposite<BeanType> {

  private static final BeanForm form = GWT.create(BeanForm.class);

  // in retrospect, I really like this code--there's hardly any
  // generic type cheese in the _use_ of the binding library
  // anywhere except the definition of the form itself.
  public BeanComposite() {
    super(form);

    FlowPanel panel = new FlowPanel();

    panel.add(bind(form.getFieldOne(), new
TextBoxEditor(CurrencyConverter.INSTANCE)));
    panel.add(bind(form.getFieldTwo(), new
LabelViewer(DefaultToString.INSTANCE)));
    panel.add(bind(form.getFieldThree(), new CreditCardEditor()));

    initWidget(panel);
  }
}

// in random UI code
BeanComposite bc = new BeanComposite();

RootWidget.get().add(bc);

bc.setBean(new BeanType());

Regarding implementing widgets with "proper support" for a databinding
library like mine, I think that's a bad idea.  At the moment, I still
like the declaration of intent implied by the Viewer and Editor
interfaces, so I'd expect BoundForm.bind() to be declared something
like this:

public interface BoundForm<B> {

  /**
   * Binds editor to field and returns editor.  <code>P</code> is
field's value type.
   */
  <P, W extends Widget & Editor<P>> W bind(Field<B, P> field, W editor);

  /**
   * Binds viewer to formula and returns viewer.  <code>P</code> is
formula's value type.
   */
  <P, W extends Widget & Viewer<P>> W bind(Formula<B, P> formula, W viewer);
}

Given HasData, it might be possible to write some really generic
implementations of Editor and Viewer that wrap an instance of HasData
to make it easier for developers to come up with an instance of Editor
to bind to, but I'm a little squirrelly about binding to arbitrary
widgets.

Thoughts?

Ian

PS I intend to look at the XForms spec as soon as I have some
time--I'm not ignoring your exhortations.  :)

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

Reply via email to