Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
759 views27 pages

GWTP

GWTP provides key concepts and features for building GWT applications using the Model-View-Presenter (MVP) pattern, including: 1) Presenters contain business logic and interact with Views through interfaces to keep them decoupled and testable. 2) Places and the PlaceManager support navigation and bookmarking of application pages. 3) The Dispatcher handles all client-server communication through a centralized command pattern. 4) The EventBus provides loose coupling for communication between application components through event publishing.

Uploaded by

ben.bracha
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
759 views27 pages

GWTP

GWTP provides key concepts and features for building GWT applications using the Model-View-Presenter (MVP) pattern, including: 1) Presenters contain business logic and interact with Views through interfaces to keep them decoupled and testable. 2) Places and the PlaceManager support navigation and bookmarking of application pages. 3) The Dispatcher handles all client-server communication through a centralized command pattern. 4) The EventBus provides loose coupling for communication between application components through event publishing.

Uploaded by

ben.bracha
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 27

GWTP

GOO-TEEPEE

By: Ben Bracha

Agenda
Background: Main concepts of GWT GWTP key concepts and features

GWT Main concepts


Java -> JS Deferred binding Code splitting (Gin/ Guice)

Java -> JS
Build complex browser-based apps in Java
Java javascript cross compiler All the goodies of Java
Rock-solid IDEs and tools Refactoring Unit testing

Deferred Binding
Generating many version of the code in compile time Only one is being loaded by particular client in run time Each version is generated per browser along with other axis defined by the application (browser, locale) In essence, this is the GWT answer for java reflection GWT.Create(SomeType.class) Code generation / replacement (for example RavelloGrey.gwt.xml)

Code Splitting
As application grows JS code downloading may take some time GWT let us split our code download what you need, when you need it GWT.runAsync defines our split point GWTP makes this clear for us using presenterproxy (TBD)

http://code.google.com/webtoolkit/doc/latest/Dev GuideCodeSplitting.html

Gin & Guice


Guice is a dependency injection (DI) framework written by Google Inversion of control (IOC) dependencies for a component are set to it externally Less usage of the new keyword Can replace actual dependencies easily (for testing..) The Injector, injector configuration Gin Guice written for GWT (lack of reflection ) http://code.google.com/p/google-guice/ http://code.google.com/p/google-gin/

Gin & Guice


*.gwt.xml: <module> ... <inherits name="com.google.gwt.inject.Inject"/> ... </module> Gin module: public class MyWidgetClientModule extends AbstractGinModule { protected void configure() { bind(SomeInterface.class).in(SomeImplementation.class); bind(MyWidgetMainPanel.class).in(Singleton.class); bind(MyRemoteService.class).toProvider(MyRemoteServiceProvider.class); } } Ginjector: [usually for top level components only] @GinModules(MyWidgetClientModule.class) public interface MyWidgetGinjector extends Ginjector { MyWidgetMainPanel getMainPanel(); }

Gin & Guice


@Inject On members and on Constructor (note that members are injected only after construction!) @ImplementedBy annotation
@ImplementedBy(PayPalCreditCardProcessor.class) public interface CreditCardProcessor { } Equivalent to: bind(CreditCardProcessor.class).to(PayPalCreditCardProcessor.class);

Singleton scope
bind(TransactionLog.class).to(InMemoryTransactionLog.class).in (Singleton.class); (default is not singleton!)

GWTP
MVP framework for building GWT applications
MVP support (presenters, presenter-widgets, nested presenters) Places (history and bookmark support) Command pattern (The dispatcher) The event bus

http://code.google.com/p/gwt-platform/

MVP
Model (entity graph) View (dumb, no logic) Presenter (logic, no UI code) Advantages
Testability Low coupling

Presenter - Proxy- View


View responsible for the widgets layout on screen Presenter Contains the business logic for a view (loading data from server, handling events..) Proxy help getting the benefits of codesplitting. If requested presenter and view will be behind a split point Binding all together (they are all singletons!!) in AbstractPresenterModule:
bindPresenter(LoginPresenter.class, LoginPresenter.MyView.class, LoginView.class, LoginPresenter.MyProxy.class);

Presenter View interactions


Interactions should be made only through interfaces The presenter defines an inner view interface (extends HasUiHandlers) implemented by the view An external interface extends UiHandlers defines operations required by the view. This is implemented by the presenter On presenter construction: getView().setUiHandlers(this);

Presenter View interactions (supervising controller pattern)


public interface UserProfileUiHandlers extends UiHandlers{ void onSave(); }

public class UserProfilePresenter extends Presenter<UserProfilePresenter.MyView, UserProfilePresenter.MyProxy> implements UserProfileUiHandlers{ public interface MyView extends View, HasUiHandlers<UserProfileUiHandlers>{ }

@Inject ExamplePresenter(final EventBus eventBus, final MyView view, final MyProxy proxy) { super(eventBus, view, proxy); getView().setUiHandlers(this); } ...

public class ExampleView extends ViewWithUiHandlers<UserProfileUiHandlers> implements MyView { ...


@UiHandler("saveButton") void onSaveButtonClicked(ClickEvent event) { if (getUiHandlers() != null) { getUiHandlers().onSave(); } }

Presenter Vs. PresenterWidget


Regular presenter-proxy-view tuple is singleton as defined by the framework What if we have some complex UI component that required presenter-view but not necessarily singleton? Use PresenterWidget-View pair
PresenterWidget has no proxy It is up to its hosting parent to instantiate it (inject!) and reveal it (add-to-slot)

Presenters Lifecycle
Phase When Called What to do

onBind() onUnbind()
onReveal() onHide() onReset()

After presenter construction Not called automatically


Just before presenter revealed Just before presenter becomes hidden when navigation occurs and the presenter is still visible after

Add handlers to view Undo everything from bind()


Any initialization or action should be done before reveal Clean any initialization you did in onReveal() The most commonly used. This is a good place to refresh presenters data

Never call lifecycle methods explicitly Always call super() when overriding

Places
A place is usually a page in the application which the user can navigate to A place attached to some presenter The PlaceManager is responsible for all place operations A place can contain state parameters (URL) for bookmarking, history
We can add navigation confirmation We can set up a default page for the application We can set up a default error-page for the application

Places
http://phone.com#!search;q=iphone
public class SearchPresenter { @ProxyStandard @NameToken("!Search") public interface MyProxy extends ProxyPlace<SearchPresenter>{} @Override public void prepareFromRequest(PlaceRequest request) { } String type = request.getParameter(); }

* When preparing from request, If your presenter needs to fetch data from server that is required for it to become visible, you can block the reveal-phase and use manual-reveal

Nested Presenters
You can build a composite-presenter made up from several child-presenters
Imply some common layout Better design (break complex structures) Reuse (presenters widgets)

Composition is done with slots


Presenter defines named slots View handles slot layout The presenter may or may not know his children
http://code.google.com/p/gwt-platform/wiki/SimpleNestedSample

Nested Presenters
public class MainPagePresenter extends Presenter<MainPagePresenter.MyView, MainPagePresenter.MyProxy> { @ContentSlot public static final Type<RevealContentHandler<?>> TYPE_SetMainContent = new Type<RevealContentHandler<?>>(); public interface MyView extends View {} @Override protected void revealInParent() { RevealRootContentEvent.fire(this, this); } }

Nested Presenter
public class MainPageView extends ViewImpl implements MyView { @UiField FlowPanel mainContentPanel; @Override public void setInSlot(Object slot, Widget content) { if (slot == MainPagePresenter.TYPE_SetMainContent) { setMainContent(content); } else { super.setInSlot(slot, content); } } private void setMainContent(Widget content) { mainContentPanel.clear(); if (content != null) { mainContentPanel.add(content); } } }

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder > <g:HTMLPanel> <npui:MainMenu /> <g:FlowPanel ui:field="mainContentPanel" /> <npui:MainMenu /> </g:HTMLPanel> </ui:UiBinder>

Nested Presenters
public class HomePresenter extends Presenter<HomePresenter.MyView, HomePresenter.MyProxy> { public interface MyView extends View {} @ProxyCodeSplit @NameToken(NameTokens.homePage) public interface MyProxy extends ProxyPlace<HomePresenter> {} @Inject public HomePresenter( final EventBus eventBus, final MyView view, final MyProxy proxy) { super(eventBus, view, proxy); } @Override protected void revealInParent() { RevealContentEvent.fire(this, MainPagePresenter.TYPE_SetMainContent, this); }

The Dispatcher
Centralized component handling all client-server communication Command pattern
Action: shared with the server and client. Presents some logic action that can be done by the client Result: shared with the server and client. Each action bounded to exactly one result, presenting the return value of the action. Handler: known only to the server. Handles an actionresult pair.
http://code.google.com/p/gwt-platform/wiki/GettingStartedDispatch

The Dispatcher
Action:
public class CreateNewDesignAction extends UnsecuredActionImpl<CreateNewDesignResult> {
private String designName; ...

Result:
public class CreateNewDesignResult implements Result { private DesignDto designDto; }

Bind server handler:


public class ServerModule extends HandlerModule { @Override protected void configureHandlers() { bindHandler(CreateNewDesignAction.class, CreateNewDesignServerActionHandler.class); }

Invoke action from client:


dispatcher.execute(new CreateNewDesignAction(text), new BaseCallback<CreateNewDesignResult>() { @Override public void onSuccess(CreateNewDesignResult result) { setCurrentDesign(result.getDesignDto()); { });

The Event Bus


Central unit for communication between loosely related objects (vs. direct method invocation) Use it for notifying the world (the application) about interesting events (for example: entity updated) Not over-use it avoid chatty application (performance) Can used private event-bus \ named-event-bus (for separation)
http://arcbees.wordpress.com/2010/08/24/gwt-platform-event-bestpractice/

The Event Bus

The Event Bus

You might also like