GWT MVP - maintaining multiple displays that are separate of one another - gwt

I have a GWT App and I am using GWT MVP with Places / Activities.
My application layout is something like
MENU | CONTENT
The Menu and the Content displays will change dynamically and one changes separately from the other. What I mean by this is that when the Content display changes I do not want to have to update the Menu display and vice versa. Both displays need to be able to respond to PlaceChangeEvents and update themselves when these occur. The problem is that each display should only update in response to certain PlaceChangeEvents, ignoring PlaceChangeEvents that are directed at the other display. However this does not work using the 'standard' GWT MVP pattern because even when each display has it's own ActivityManager they will automatically pick up ALL PlaceChangeEvents because there is a single PlaceController listening on a single EventBus. The only way I can see to do this is by having two EventBus's and two PlaceControllers - one for the Menu and one for the Content. So my question is whether this is a good solution or is there a simpler/better way that I am missing? One problem with this solution is that the PlaceHistoryHandler can only be registered with one of the EventBus's.

Place changes are actually controlled by ActivityMappers. They get a Place and return the corresponding Activity. This is where you control how Places are mapped to Activities:
You need to create two ActivityMappers (MenuActivityMapper, ContentActivityMapper) and then instantiate two ActivityManagers each with it's own ActivityMappers. Then for each ActivityManager you call setDisplay(AcceptsOneWidget display) where for each you pass in an area (display) where it will show it's content.
For menu you will probably only use one Activity, since it's available in all Places. So MenuActivityMapper.getActivity() will always return the same instance of the MenuActivity. To enable MenuActivity to still adapt it's look based on place changes, MenuActivity should listen to PlaceChangeEvents.

Related

UWP App with multiple frames using the MVVM pattern

Is there any library / framework that could simplify Universal Windows Platform app development of the application that contains multiple Frames.
I mean, using MVVM Light or BezySoftware MVVM-Navigation the application is highly tied to the idea of navigating between different pages that are hosted by single frame.
The UI I try to develop consist of multiple content frames (main, left, right) which content varies. I need something that will let me navigate easily between different views (by placing these views into appropriate frame) and provide the same features I would have with BezySoftware MVVM-Navigation, so:
handling of the view model state persistence
the ability to activate / query deactivate view models
back button feature
Few different options:
Combination of a single navigation service injected into your view model AND user controls for areas that need to be repeated view to view (e.g. a tabs, status bars, etc). With this route, every time you create a new view you would paste in the common user controls that need to appear. You would also be able to expose bindable properties from said user controls.
Combination of ContentControl, DataTemplate, and DataTemplateSelector to load in either an entire view (Page) or fragments of XAML. As one person pointed out you cannot use DataType attribute, instead you use the DataTemplateSelector class to do the mapping for you. With this approach you can also use triggers to dynamically change the template (content) based on changes to properties on your view model and/or user interactions.
A mix between 1 and 2 above.
I might right the whole thing right here, but it too lengthy. I just recommend you see this article to get your answer.
MVVM patter in UWP

Navigating hierarchical data, FrameAdapter, Frame control

I want to implement navigating a tree structure like it is done in e.g. the WinRT file picker. I then want to be able to drop this behavior as part of any page.
My current attempt, is to try and register a secondary FrameAdapter/INavigationService in the container and use that for a frame that is different from the app root frame. So far, I could not get it to work.
My motivation behind that, is, that I do not want to reimplement sth. that the INavigationService already provides.
Basic structure:
ShellView that represents the general app layout (header, footer, navigation) and is currently an OneActive conductor.
Frame control (x:Name="ActiveItem") on the ShellView inside which the hierarchical navigation should occur
The chosen conductor has no relevance yet, since I'll probably have to nest the FrameControl inside another view later to really set up a MDI interface. I'll will want to have multiple screens that should be able to hierarchically navigate
I could not find a CM WP7 example of such a scenario
Can you help me out here?
My problems so far:
How do I access the container from a view code-behind without resorting to using the Application.Current. I figured, it is in the code-behind where I would want to setup the secondary FrameAdapter, since it is here that I have access to the FrameControl
How do I setup the INavigationService so that the initial loading by CM (populating the ActiveItem) is registered with it. There does not seem to be a navigation event for this initial display of the ActiveItem.
Many thanks in advance,
Tobias
PS: I have cross-posted to the Caliburn Micro discussions (Discussion over at CodePlex CM)

GWT Editors for readonly and edit mode

GWT's Editor framework is really handy and it can not only be used for editing POJOs but also for read-only display.
However I am not entirely sure what the best practice is for doing inline edits.
Let's assume I have a PersonProxy and I have one Presenter-View pair for displaying and editing the PersonProxy. This Presenter-View should by default display the PersonProxy in read-only mode and if the user presses on a edit button it should allow the user to edit the PersonProxy object.
The solution I came up with was to create two Editors (PersonEditEditor and PersonDisplayEditor) that both added via UiBinder to the View. The PersonEditEditor contains
ValueBoxEditorDecorators and the PersonDisplayEditor contains normal Labels.
Initially I display the PersonDisplayEditor and hide PersonEditEditor.
In the View I create two RequestFactoryEditorDriver for each Editor and make it accessable from the Presenter via the View interface. I also define a setState() method in the View interface.
When the Presenter is displayed for the first time I call PersonDisplayDriver.display() and setState(DISPLAYING).
When the user clicks on the Edit button I call PersonEditDriver.edit() and setState(EDITING) from my Presenter.
setState(EDITING) will hide the PersonDisplayEditor and make the PersonEditEditor visible.
I am not sure if this is the best approach. If not what's the recommended approach for doing inline edits? What's the best way to do unit-testing on the Editors?
If you can afford developing 2 distinct views, then go with it, it gives you the most flexibility.
What we did in our app, where we couldn't afford the cost of developing and maintaining two views, was to bake the two states down into our editors, e.g. a custom component that can be either a label or a text box (in most cases, we simply set the text box to read-only and applied some styling to hide the box borders).
To detect which mode we're in, because we use RequestFactoryEditorDriver (like you do), we have our editors implement HasRequestContext: receiving a null value here means the driver's display() method was used, so we're in read-only mode. An alternative would be to use an EditorVisitor along with some HasReadOnly interface (which BTW is exactly what RequestFactoryEditorDriver does to pass the RequestContext down to HasRequestContext editors).
Yes,Presenter-View pair should be. But Here two ways to achieve this feature if you like to go with:
1) Integrate Edit/View code design in one ui.xml i.e.Edit code in EDitHorizonatlPanel and View code in ViewHorizontalPanel.The panel has different id. By using id, show/hide panel with display method. if getView().setState() ==Displaying then show ViewHorizontalPanel and if getView().setState()==Editing then show EditHorizontalPanel.
2) Instead of using labels, Use textboxes only. set Enable property is false when you need it in view mode otherwise true
You have created two Presenter/view but I think if Edit/View function has similar code so no need to rewrite similar code again and again for view purpose.
If a big project has so many Edit/View function and you will create such type of multiple View/Presenter than your project size become so huge unnecessary.
I think that whatever I have suggest that might be not good approach but a way should be find out which help to avoid code replication.

GWT UiBinders Interaction between modules

Im new to GWT, this should be a simple question i hope.
Imagine that i made two Uibinders Modules or two independent widgets.(this a simplify example to expose my problem)
one is a set of buttons (ButtonPanel) and the other image to been show when i press a button from the previous panel(ImagePAnel) with a label to be the title of the image.
How can i reach the wiget the imagePanel to actuate when there are a handler click from the buttons in the (ButtonPanel)
Thanks for the help.
I recommend you to use MVP Pattern for Development and add all events in the Presenter.
Or Else you can use the following technique within the UIBinder's Java File
#UiHandler(value={"openButton"})
public void onOpenButtonClick(ClickEvent clickEvent){
//ADD THE BUTTON LOGIC HERE
}
Just Create an Object of the Images & the ImagePanel to be loaded and add it on button click using this.
I can't say I understand exactly what you are trying to accomplish but in general the best way for different components in a GUI application to communicate is to use the eventbus pattern. There's one global Eventbus object in the application that lets components subscribe to a specified type of event that are fired from any place in your application. This way you avoid spaghetti code and your components are loosely coupled.
http://code.google.com/webtoolkit/articles/mvp-architecture.html#events
I typically create a third component that is the container for the Button and Image components you defined. This component sets itself as a callback for the two and contains logic to integrate the two.

GWT - connect two modules via EventBus

We use MVP with custom EventBus to navigate across the views. One of our GWT module loads an ebook within a view. We have a button named "Expand", which upon clicked, loads the ebook in expanded mode thereby hiding the header, footer, etc.
Let us say the view (UiBinder) with "Expand" button is named as "ShowEbookView". Upon clicking "Expand" button, the ClickEvent is captured and fired to the EventBus. The logic onExpand(final ExpandEvent expandEvent) is written in the same "ShowExpandedMod" class.
Everything is okay, but we have a button named "Popout" in the expanded mode, which when clicked, should open the Ebook in a NEW page! We need to abstract the "ShowExpandedMod" class so that it can operate with the EbookId and can be used in the new page.
We have created a new Module with EntryPoint class, HTML page and UiBinder page for this new popout window. I am not sure how to proceed now with the abstraction and to use EventBus across different modules to load the same content ... (with re-usability ofcourse)
I've explained to my best, but perhaps not very clear! Please let me know if you want more details.
Thanks!
When you open a new window in browser you basically get a new instance of your GWT app. You can not use EventBus across different browser windows, i.e. across different GWT module instances.
What you can do is:
Add an argument to the Popout page URL. This is easies done via "history tokens" (fragment identifiers), like this http://yourdomain.com/popout.html#theIdOfTheDocument. Then you can retrieve the token via History.getToken()
Use DOM to communicate between browser windows: window.open() in javascript opens a new window and returns a reference to DOM of the new window. You can then access properties and functions of the new window. This is all javascript, in order to make this work in GWT you'll need to wrap it in JSNI.
Try and use MVP4G, in specific - take a look at their multi-modules feature (which utilizes GWT's code splitting capabilities).
This should make things like multiple EventBus's and cross-module event triggers a lot easier to handle.