Closed GoogleCodeExporter closed 9 years ago
Alexei, can you please explain in more details and provide examples of the
issue? We didn't notice yet problems
with UiBinder.
Original comment by alexande...@gmail.com
on 2 Dec 2009 at 2:39
The problem begins when view/widget defined in UiBinder xml format contains
another
views/widgets which are also defined in UiBinder xml format. In this case
UiBinder code
will instantiate all contained views by itself and mvp4g will also instantiate
another
instances of the same views, thus every contained view will have two instances
and only
one of them will be connected to presenter (and it will be one that is not
displayed)
Original comment by alexei....@gmail.com
on 3 Dec 2009 at 9:37
Could you attach the project where you have this error so that I can easily
reproduce it? Thanks.
Original comment by plcoir...@gmail.com
on 3 Dec 2009 at 5:02
Probably I have the same problem with UiBinder and nested widgets.
Please take a look at the attached project.
Thanks
Original comment by ceppelli
on 13 Jan 2010 at 7:10
Attachments:
Thanks, I will look at your project and see where the problem comes from.
Original comment by plcoir...@gmail.com
on 15 Jan 2010 at 12:42
I imported your project into eclipse and it worked fine. What problem do you
have?
Original comment by plcoir...@gmail.com
on 16 Jan 2010 at 4:04
The application contains 2 widgets:
1. MyViewUiBinder.ui.xml
2. MyLabelUiBinder.ui.xml
The MyViewUiBinder.ui.xml instantiates the MyLabelUiBinder.ui.xml.
I wrote some line in the code which print on the standard output some
information during the startup of the
application.
[MyLabelUiBinder] MyLabelUiBinder() 0
[MyViewUiBinder] MyViewUiBinder()
[MyViewUiBinder] createView()
[MyLabelUiBinder] MyLabelUiBinder() 1
[MyViewPresenter] onInit()
[MyLabelUiBinder] createView() 0
[MyLabelPresenter] onInit()
As you could see the "MyLabelUiBinder()" is instantiated 2 times ( this is
wrong). In the MyLabelPresenter.java
the onInit() and onUpdateLabel(String) event wont be applied to the displayed
MyLabelUiBinder.ui.xml widget
but to the second one (probably) which is instantiated by the mvp4j framework.
I hope my description was clear.
Thank in advance
Original comment by ceppelli
on 18 Jan 2010 at 2:26
Thanks for your description. I now understand the problem.
However I'm not sure if this is a bug. My interpretation of MVP + event bus
pattern
is that each component should be independant. You can remove any of them, it
won't
impact the rest of the application. I think that having a view of a presenter
defined by the view of another presenter (which is the case here) doesn't
respect
this rule. If you ever want to remove label presenter, you need to also modify
MyViewUiBinder.ui.xml and remove the label.
I would follow a different strategy. I would remove label binder from view
binder
and create a new event changeWidget. This event would be thrown by
LabelPresenter
when application starts to tell the application to set its view. This event
would be
handle by ViewPresenter that, when triggered for this event, will add the
widget.
You would then have no link between the two views.
You will find attach the project you sent implementing this strategy.
What do you think?
Original comment by plcoir...@gmail.com
on 19 Jan 2010 at 12:21
Attachments:
Thanks you for you answer.
I see you point and also I took a look at your code, I'm not really an expert
in pattern and architectures, so when I'm reading you explanation, I only could
agree with you
that this is not a bug.
The new features UiBinder introduced in GWT 2.0 is really great from my point
of view, it is like the mxml in the Adobe Flex framework. Now it really easy to
create a
complex visual component, deal with the css and the most important thing it is
possible in an easy way to make a composition of the widgets already created
without
writing new code (just xml).
With your approach the creation of the widgets is always driven by the mvp4g
framework (this is fine) but the composition of it in the application is
hardcoded in the
code:
@Event(handlers={MyViewPresenter.class})
public void onChangeWidget(Widget w){
view.getPanel().add(w);
}
What do you think? Maybe It would be possible instantiate the presenter in the
constructor of the UiBinder widget and register it the EventBus? (As I said I'm
not an
expert, maybe I make a mistake)
At the moment I'm dealing with a medium GWT application I wrote. After some
mouths is not more possible to make new development (From the beginning I
didn't
spend to much time in architecture designing, MY FAULT). Now I'm thinking to
rewrite it from scratch and I'm making some experiments.
What I see until now about mvp4g was great (It will resolve my "spaghetti code
issue" and will improve the effectiveness of the unit test). But I still have
some problem
how to use it in some situations, maybe you have some suggestions.
1. As explained before the composition of widgets (especially the new UiBinder
version).
2. The application should show/use multiple widgets of the same kind, but the
amount of them is not know at the beginning, which approach should I use in
order to
create new presenter/view pair on demand?
Thanks
Original comment by ceppelli
on 19 Jan 2010 at 3:13
I can see why you would like to do this if you're used to flex. I guess it may
be
possible to integrate this to Mvp4g thanks to @UiField(provided=true). Maybe
for a
future version?
Just to make sure we talk about the same thing. For me a view is made of
widgets,
and each view is managed by one presenter.
So Mvp4g let you manage composition of widgets inside a view.
Now for composition of views inside a view, on this point, I do follow a
different
approach, more like "no link, only event". If a presenter has a view that can
contains other views, it just tells the rest of the application about it
(thanks to
events) without knowing the other views. This way your application can really
be
dynamic.
In case you have views inside a view, for example, if you have:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder>
<g:FlowPanel>
<v:MyMenu></v:MyMenu>
<v:MyMainPage></v:MyMainPage>
</g:FlowPanel>
</ui:UiBinder>
How would you change your content of your main page? What would you do if you
decide
to make your menu dynamic (eg: you need to load a different menu according to
your
user rights)?
In the case the menu never changes, you can also add a menu widget to MainView
and
have only one presenter to manage these two elements.
Concerning your second question, you can look at this discusion that talks
about the
same problem and let me know what you think about this solution:
http://groups.google.com/group/mvp4g/browse_thread/thread/50ff74971d8c0006/3dad9
c44c9
3f1485?lnk=gst&q=portlet#3dad9c44c93f1485
Thanks
Original comment by plcoir...@gmail.com
on 19 Jan 2010 at 11:59
"I can see why you would like to do this if you're used to flex. I guess it may
be
possible to integrate this to Mvp4g thanks to @UiField(provided=true). Maybe
for a
future version?"
Just adding my vote to this - I spent much time trying to use the
@UiField(provided=true) to integrate nested UIBinder modules and MVP but was
unsuccessful. If anyone has any success, or if we can get these working nicely
please post your example here. This functionality, imho, makes or breaks this
design
pattern as I cannot code GWT without MVP, and I cannot code GWT without
breaking my
views up into separate, nested UIBinder modules.
Thanks.
Original comment by NirmalPS...@gmail.com
on 6 Feb 2010 at 4:12
I just transformed the GWT Mail example using Mvp4g. You can look at it by
downloading the last example of the 1.1.0 example. It gives you an example of
how to
use UiBinder with MVP. For now, it's not possible to directly inject view
inside
other views, you need to do it throught events.
But, after having transformed the GWT Mail example, I realized how practical it
would be to inject view inside other views when using UiBinder. I will work on
it
for the 1.2.0 release.
Original comment by plcoir...@gmail.com
on 6 Feb 2010 at 2:46
GIN has been integrated with Mvp4g so you can use GIN injection features to
inject
view inside other views.
You can inject a view directly into another view this way:
-declare the injected view as a singleton
-insert this view to your other view thanks to GIN @Inject
=> this way the same instance will be injected into your view and inside the
presenter (you don't need to use events)
//Injected view
@Singleton
public class MailListView extends ResizeComposite implements
MailListPresenter.IMailListView {...}
//Other View
public class MailView extends Composite implements IMailView {
interface Binder extends UiBinder<DockLayoutPanel, MailView> {
}
private static final Binder binder = GWT.create( Binder.class );
@UiField( provided = true )
MailListView mailList;
@Inject
public MailView( MailDetailView mailDetail ) {
this.mailList = mailList;
initWidget( binder.createAndBindUi( this ) );
}
However you need to make sure that the presenter that manages the injected view
binds its view before (or right after) it is injected into the other view,
otherwise
this view will do nothing.
You can download the last examples of the 1.2.0 snapshot and look at
MailWithMvp4g
to see a working example.
Original comment by plcoir...@gmail.com
on 25 Apr 2010 at 10:45
Just another thought on this, what would you do if you want to inject two
different
instances of that view?
I believe the option here is to use Gin's @Named annotation in conjuntion with
the
above, so that you name your singletons... Can't think of a better way... Maybe
that
helps someone. Maybe there is a better way?
Original comment by christop...@gmail.com
on 18 May 2010 at 9:41
Attached is an example where you have the same menu at the bottom and at the
top of
the screen. Both of these menus are displayed using GIN injection.
The workaround to be able to have 2 menus is to have 2 presenter classes and 2
view
classes.
You would have something like that:
@Presenter(view=MainMenuView.class)
public class MainMenuPresenter extends
BasePresenter<MainMenuPresenter.IMenuView,
MainEventBus> {
//here you define all your code
...
}
@Presenter( view = MainBottomMenuView.class )
public class MainBottomMenuPresenter extends MainMenuPresenter {
//this class is empty, it's only use to define a second instance of the menu
}
public class MainPageView extends Composite implements IMainPageView {
@Inject
public MainPageView( MainMenuView topMenu, MainBottomMenuView bottomMenu ) {
Original comment by plcoir...@gmail.com
on 19 May 2010 at 2:36
Attachments:
plcoirier,
This Gin injection in the view is perfect! But doesn't seem to work when using
multi-modules. I want to inject presenters from sub-modules in my root view.
Imagine in the MailView injecting MailDetailView and ShortcutsView from a
child-module (extends Mvp4gModule). If I try as you mention, I get a
compilation error on my main view not having an empty constructor.
Then if I try to annotate the handlers for the start event with the presenters
from the sub-module it complains that it is a different event-bus.
Do you know of a way to do this?
Original comment by javier.a...@gmail.com
on 24 Aug 2010 at 7:39
Each module has its own Ginjector so you can't inject a view from one module to
another one.
The only way to inject a view from another module is to use events. You could
have 2 events setMailDetailView & setShortcutsView that the child module can
forward to the parent module with the needed views. This is the strategy
followed in the Mvp4gModule example.
Original comment by plcoir...@gmail.com
on 25 Aug 2010 at 10:17
Original issue reported on code.google.com by
alexei....@gmail.com
on 29 Nov 2009 at 1:49