Now when I want to use MyView inside a different UiBinder widget I inject the interface and use it along with @UiField(provided = true).
That works great but as a little downside I have to re-declare Widget methods in my MyView interface if I want to call them directly in UiBinder, e.g. setWidth/setHeight/setStyleName.
For setter methods that also works, but now I need to add some styles to MyView. In UiBinder you would normally do <my:MyView addStyleNames="list of styles"/> but that fails in case of my view interface (error is: setAddStyleNames() is not declared). Actually UiBinder special treats "addStyleNames" for normal widgets (it works with <my:MyViewImpl addStyleNames=...>) but it stops doing so when it sees something that does not extend Widget I guess. To solve this I am forced to create an Interface for my UiBinder inline CssResource just to be able to do: myView.asWidget().addStyleName(..).
How do you guys work with view interfaces in UiBinder? Are there better ways than mine?
My proposed RFE for UiBinder would be that UiBinder recognizes interfaces that extend IsWidget and then generates code that delegates to view.asWidget().method() as long as "method()" is available in Widget or UiObject class. Any opinions?
In the rare cases where a widget is complex enough to deserve an MVP pattern, I generally use the XViewImpl directly in the UiBinder (YViewImpl) of the other widget, and create the XPresenter from within the YPresenter (asking the YView for an XView, similar to what Wave is doing –when creating those things dynamically though in their case–, see http://www.google.com/events/io/2010/sessions/gwt-continuous-build-te... )
I only ever need it on a very few cases though, I don't use MVP as a general rule on widgets, only on "activities" (or similar), that is, coarse-grained. And I never needed to add specific styling or similar to these widgets.
For complex widgets that need to be reused easily and widely, I'd rather follow the Cell widget's way: the presenter is internal to the widget; MVP is an implementation detail, from the outside it's just a widget like any other.
Last but not least, there's still the idea of making UiBinder more Guice-friendly, so you could provide a factory to the UiBinder rather (or in addition) to @UiFactory methods. That would allow the use of a Ginjector or an AssistedInject factory shared by several UiBinder throughout the app, instead of having to duplicate "trampoline" @UiFactory methods in each and every "ViewImpl": http://code.google.com/p/google-web-toolkit/issues/detail?id=6151 The only issue for now (AFAICT) is to find the time to implement it.
> Now when I want to use MyView inside a different UiBinder widget I inject > the interface and use it along with @UiField(provided = true).
> That works great but as a little downside I have to re-declare Widget > methods in my MyView interface if I want to call them directly in UiBinder, > e.g. setWidth/setHeight/setStyleName.
> For setter methods that also works, but now I need to add some styles to > MyView. In UiBinder you would normally do <my:MyView addStyleNames="list of > styles"/> but that fails in case of my view interface (error is: > setAddStyleNames() is not declared). Actually UiBinder special treats > "addStyleNames" for normal widgets (it works with <my:MyViewImpl > addStyleNames=...>) but it stops doing so when it sees something that does > not extend Widget I guess. To solve this I am forced to create an Interface > for my UiBinder inline CssResource just to be able to do: > myView.asWidget().addStyleName(..).
> How do you guys work with view interfaces in UiBinder? Are there better > ways than mine?
> My proposed RFE for UiBinder would be that UiBinder recognizes interfaces > that extend IsWidget and then generates code that delegates to > view.asWidget().method() as long as "method()" is available in Widget or > UiObject class. Any opinions?
The issue described by Jens doesn't seem to inherently involve MVP -- I don't quite follow the first part of your response. It seems like any widget, no matter how "dumb," could implement IsWidget directly rather than extend Composite or a more concrete Widget supertype.
Do you think his suggested approach is feasible, namely having UiBinder be able to correctly interpret Widget attributes/setters (like addStyleNames="..") for IsWidget types?
On Friday, July 20, 2012 2:43:31 PM UTC-4, Thomas Broyer wrote:
> In the rare cases where a widget is complex enough to deserve an MVP > pattern, I generally use the XViewImpl directly in the UiBinder (YViewImpl) > of the other widget, and create the XPresenter from within the YPresenter > (asking the YView for an XView, similar to what Wave is doing –when > creating those things dynamically though in their case–, see > http://www.google.com/events/io/2010/sessions/gwt-continuous-build-te... > )
> I only ever need it on a very few cases though, I don't use MVP as a > general rule on widgets, only on "activities" (or similar), that is, > coarse-grained. And I never needed to add specific styling or similar to > these widgets.
> For complex widgets that need to be reused easily and widely, I'd rather > follow the Cell widget's way: the presenter is internal to the widget; MVP > is an implementation detail, from the outside it's just a widget like any > other.
> Last but not least, there's still the idea of making UiBinder more > Guice-friendly, so you could provide a factory to the UiBinder rather (or > in addition) to @UiFactory methods. That would allow the use of a Ginjector > or an AssistedInject factory shared by several UiBinder throughout the app, > instead of having to duplicate "trampoline" @UiFactory methods in each and > every "ViewImpl": > http://code.google.com/p/google-web-toolkit/issues/detail?id=6151 > The only issue for now (AFAICT) is to find the time to implement it.
> On Friday, July 20, 2012 6:42:02 PM UTC+2, Jens wrote:
>> Hi,
>> I am using GIN + MVP + UiBinder so I end up with having:
>> Now when I want to use MyView inside a different UiBinder widget I inject >> the interface and use it along with @UiField(provided = true).
>> That works great but as a little downside I have to re-declare Widget >> methods in my MyView interface if I want to call them directly in UiBinder, >> e.g. setWidth/setHeight/setStyleName.
>> For setter methods that also works, but now I need to add some styles to >> MyView. In UiBinder you would normally do <my:MyView addStyleNames="list of >> styles"/> but that fails in case of my view interface (error is: >> setAddStyleNames() is not declared). Actually UiBinder special treats >> "addStyleNames" for normal widgets (it works with <my:MyViewImpl >> addStyleNames=...>) but it stops doing so when it sees something that does >> not extend Widget I guess. To solve this I am forced to create an Interface >> for my UiBinder inline CssResource just to be able to do: >> myView.asWidget().addStyleName(..).
>> How do you guys work with view interfaces in UiBinder? Are there better >> ways than mine?
>> My proposed RFE for UiBinder would be that UiBinder recognizes interfaces >> that extend IsWidget and then generates code that delegates to >> view.asWidget().method() as long as "method()" is available in Widget or >> UiObject class. Any opinions?
On Friday, July 20, 2012 6:42:02 PM UTC+2, Jens wrote: > Actually UiBinder special treats "addStyleNames" for normal widgets (it > works with <my:MyViewImpl addStyleNames=...>) but it stops doing so when it > sees something that does not extend Widget I guess.
which is registered in com.google.gwt.uibinder.rebind.UiBinderWriter.registerParsers()
That method already contains a code comment:
// TODO(rjrjr): Allow third-party parsers to register themselves // automagically
Then again, if such a parser were registered, it probably shouldn't be registered for IsWidget, but instead for a new Interface that contains the addStyleName method.