Hi Thomas.

On Aug 27, 6:22 pm, Thomas Broyer <t.bro...@gmail.com> wrote:
> On 27 août, 17:15, "rocha.po...@gmail.com" <rocha.po...@gmail.com>
> wrote:
>
>
>
> > Hi all.
>
> > I've been trying to use the UIBinder, i like it a lot. At the same
> > time i've replaced my own MVP implementation with gwt-presenter (which
> > is cleaner than what i had), but there's one bit i can't figure out by
> > myself regarding dependency injection with GIN.
>
> > I have a MainPresenter which is retrieved by the injector interface
> > after i instantiate the injector. This one instantiates the
> > corresponding MainView using DI, and the actual layout is defined in a
> > UiBinder xml file. This works fine, until i try to add another of my
> > View objects into the MainView UiBinder file. Something like:
> > <gwt:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
> >    ...
> >    xmlns:stats="urn:import:my.package.for.statistics">
> >      ...
> >      <stats:StatsView ui:field="statsView"/>
> >      ...
> > </gwt:UiBinder>
>
> > One question and one issue.
>
> > 1) How do you instantiate your Presenter objects? I have a
> > StatsPresenter for the StatsView, but if i simply use the UiBinder
> > like in here, it will never be instantiated. I've 'fixed' this by
> > adding a reference to this StatsPresenter from the MainPresenter -
> > which is injected - but only so that one is created, it's not like i
> > need that reference there.
>
> If your presenter has no public method of any kind (i.e. a
> StatsPresenter instance has to exist, but nothing will actually do
> anything with it; e.g. it just listens to events from the view and
> fire events on the event bus and/or listens to events from the
> eventBus and updates the view accordingly), then maybe you can reverse
> the dependency and have StatsView instantiate its StatsPresenter and
> keep a reference to it in a private field (StatsPresenter would still
> be an independent class that could be tested without StatsView and
> with mock StatsPresenter.Display instead); this would make StatsView a
> "simple" Composite widget (that happens to use MVP but this becomes an
> implementation detail).
>
> Did I correctly understand your problem?

Yes. Doing it the way you suggest works fine, i've just gave it a try
- thanks!. I answer inline below, but with this new structure there's
one thing related to gwt-presenter. The constructor of a Presenter (a
WidgetPresenter) looks like:
(final Display display, EventBus eventBus, final DispatchAsync
dispatch)

where the Display is the interface for the View. If i'm instantiating
the Presenter inside the View, then i need to define the EventBus and
DispatchAsync as dependencies for the View, which are simply passed on
to the Presenter along with the View instance itself. It works... but
these are not really dependencies on the View.

> > 2) Given my solution above, i need to make sure that the StatsView is
> > a singleton, otherwise the Presenter instantiates a new StatsView
> > which is different from the one created by the UiBinder.
>
> Er, I don't understand...

This was just due to the way i was using it. The UiBinder would create
a StatsView instance, and the StatsPresenter, which i would inject in
another class, would get a StatsView injected itself - a different
one. So making both singleton would help, but it was just a big mess.

> > Again i try
> > to use dependency injection by defining in the MainView a StatsView
> > field as in:
>
> >     @UiField(provided=true)
> >     StatsView statsView;
>
> If StatsView has dependencies that should be injected view GIN in its
> constructor then yes, that the way to go
>
> > I then add in my injector:
> > bind(StatsView.class).in(Singleton.class);
>
> See above, I don't understand why it has to be a singleton (actually,
> I believe it shouldn't)
>
> > but either this or using a Provider method instead gives me the
> > following:
> > 00:01:18.766 [ERROR] Failed to create an instance of 'MainView' via
> > deferred binding java.lang.NullPointerException: null at
> > com.google.gwt.user.client.ui.ComplexPanel.add(ComplexPanel.java:77)
> > at com.google.gwt.user.client.ui.VerticalPanel.add(VerticalPanel.java:
> > 53) at
> > ...
>
> > Any hints on this? I can't figure out what i'm doing wrong.
>
> Have you assigned a StatsView instance to your statsView field? When
> using @UiField(provided=true), you're telling UiBinder to not
> instantiate a StatsView but instead use the one you're providing; i.e.
> UiBinder will read the field value and use that to build the UI
> instead of building the UI and write the field's value with the widget
> it instantiated.

Ok... this was it. For some reason i built the idea that provided=true
meant injected=true, and that the UiBinder would use DI to get an
instance of the object. Thanks.

> Have a look at the examples on the UiBinder wiki page, section
> named... "Using a widget that requires constructor args" 
> (sic!)http://code.google.com/p/google-web-toolkit-incubator/wiki/UiBinder#U...
>
> (the @UiFactory method –first example, without method arguments– would
> allow you to use a Provider<StatsView> for instance and have the
> factory return provider.get(); this would be handy when you need to
> have several StatsView instances in the same .ui.xml)
>
> (@UiConstructor, or the @UiFactory with arguments, wouldn't fit with
> DI via GIN, as the values come from the ui.xml itself)

Thanks again,
  Ricardo
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com
To unsubscribe from this group, send email to 
google-web-toolkit+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to