After finishing the work on the 'plugin'-feature and a lot of testing, Nalu v1.0.0 is released and the artifacts are deployed to Maven Central.
Nalu is a framework that helps you to create GWT applications similar to GWT Activities & Places - with less code - and offers the following features:
* Route based navigation
* Supports HTML links and programmatically routing thanks to a router.
* Full support of the browser's back- forward- and reload-button.
* An optional loader that will be executed at application start to load data from the server.
* A client side context, router and event bus which will be automatically injected in every controller, filter, loader and handler. (Handler have only access to the context and the event bus)
* Filters to intercept routing.
* Separation of views into a controller and a component with framework sided instantiation.
* A controller life-cycle using `start`-, `mayStop`- and `stop`- similar to GWT Activities.
* Controller based handler manager, that will remove all handlers from the event bus in case the controller is stopped to prevent memory leaks (handler registrations must be added to the manager).
* Support for UiBinder (nalu-plugin-gwt)
* Nalu composites to support smaller units
* Controller & component caching
* Component creation inside a controller to support GWT replacement rules and static factory methods
* Multi Shell Support
* works with nearly every widget lib (tested with: GWT, GXT, Domino-UI, Elemento, Elemental2, GWT-Meterial)
* Supports Maven multi module projects to separate an application in smaller parts (plugin feature)
More informations about Nalu can be found here:
https://github.com/NaluKit/nalu
There are already several examples available that shows the implementation of Nalu's features and how to create an application using Nalu:
https://github.com/nalukit/nalu-examples
To start playing around, you can use the Nalu Project generator located here:
http://www.mvp4g.org/gwt-boot-starter-nalu/GwtBootStarterNalu.html#application/setUp
(The project generator is based on Nalu and uses Domino-UI (https://github.com/DominoKit/domino-ui) Thanks Ahmad for creating the UI)
To get in touch with the developers, use the Nalu Gitter room: https://gitter.im/Nalukit42/Lobby.
Last but not least, I would like to thank everybody who helped getting Nalu done.
Showing posts with label place. Show all posts
Showing posts with label place. Show all posts
Saturday, December 1, 2018
Friday, October 26, 2018
Nalu - A New Framework
Mvp4g is awesome and with the new version ready for J2CL. No doubt, a great framework. But it takes some time to understand it and it behaves different than other GWT frameworks we know (f.e.: GWT Activities & Places),
Based on a discussion with Colin Alworth and Ignacio Baca Moreno-Torres, the framework developer team started to rethinking the approaches of MVP4G and defined a list of goals, that a new framework should provide:
Today, we are very close to release version 1.0.0 of this new framework!
The new framework is called Nalu.
You will find more informations about Nalu here: https://github.com/NaluKit/nalu
There are a few examples that shows how to use Nalu: https://github.com/nalukit/nalu-examples
And to start creating you own experiences, there is a boot starter project, that generates a ready to import Nalu Maven project:
http://www.mvp4g.org/gwt-boot-starter-nalu/GwtBootStarterNalu.htmlhttp://www.mvp4g.org/gwt-boot-starter-nalu/GwtBootStarterNalu.html
The Project generator uses Domino-UI, a new awesome widget lib ready for J2CL!
If you have questions about Nalu, please use the Gitter Room.
Based on a discussion with Colin Alworth and Ignacio Baca Moreno-Torres, the framework developer team started to rethinking the approaches of MVP4G and defined a list of goals, that a new framework should provide:
- Fully support of the browser's back- forward- and reload-button.
- An optional loader that will be executed at application start to load data from the server.
- A client side context, router and event bus which will be automatically injected in every controller. (Handler have only access to the context and the event bus)
- Filters to intercept routing.
- Full history support.
- Separation of views into a controller and a component with framework sided instantiation.
- A controller life-cycle using
start-,mayStop- andstop- similar to GWT Activities. - Supports HTML links and programmatically routing thanks to a router.
- Controller based handler manager, that will remove all handlers from the event bus in case the controller is stopped to prevent memory leaks (handler registrations must be added to the manager).
- Support for UiBinder (nalu-plugin-gwt)
- Nalu composites to support smaller classes
- Controller & component caching
- Component creation inside a controller to support GWT replacement rules and static factory methods
- Ready to use with J2CL
Today, we are very close to release version 1.0.0 of this new framework!
The new framework is called Nalu.
You will find more informations about Nalu here: https://github.com/NaluKit/nalu
There are a few examples that shows how to use Nalu: https://github.com/nalukit/nalu-examples
And to start creating you own experiences, there is a boot starter project, that generates a ready to import Nalu Maven project:
http://www.mvp4g.org/gwt-boot-starter-nalu/GwtBootStarterNalu.htmlhttp://www.mvp4g.org/gwt-boot-starter-nalu/GwtBootStarterNalu.html
The Project generator uses Domino-UI, a new awesome widget lib ready for J2CL!
If you have questions about Nalu, please use the Gitter Room.
Monday, June 20, 2011
Navigation Control
One of the main features introduced in Mvp4g-1.3.0/1.3.1 is the navigation feature. This feature allows you to detect when a user leaves a page. The most common use of this feature is when the user is on a page with a form. Before leaving this type of page, you usually want to check if all the data entered by the user is saved. If not, you ask the user to confirm if he wants to leave the page without saving or if he wants to cancel the navigation.
To demonstrate this feature, I'm going to reuse the example developed for the previous tutorial and add a form on page 2. You can download the example here (Project: Mvp4g_Navigation_Control).
This form is pretty simple with only two fields (first and last name) and a save button.
We have the following screen:
Like the rest of the application, we follow the Reverse MVP pattern to develop our form. We then have the following interfaces:
The first questions we need to answer are what does it mean to leave a page and when does it occur? In the GWT world, we have a single page application so we can't consider that a user goes to a new page when it loads a new HTML file. Instead the notion of places has been introduced. A place defines where the user is in the application. So leaving a page means going to a new place.
In Mvp4g, you go to a new place by firing an event. Thus the first step to control user navigation is to indicate which event brings the user to a new place.
In order to do this, a new attribute has been added to the @Event annotation, 'navigationEvent'. If set to true, it indicates that when this event is fired, the user is brought to a new place. In our example, we have two place events, goToPlace1 and goToPlace2.
Now that we have configured our navigation events, we need to create a navigation confirmation to control the navigation. In order to do this, we need to create a class that implements NavigationConfirmationInterface. This interface defines the following method:
To create a NavigationConfirmationInterface, I usually have the presenter implement it directly. This way, I can easily have access to the data and the view to confirm the navigation and I limit the number of classes.
In our example, we want to control that data entered in the form has been saved. In order to do this, we just check if the data displayed in the view matches the data of the local variable. If it doesn't, we display a message to the user using the default browser confirm popup. If data matches or if the user wants to leave the page anyway, we confirm the event by calling the fireEvent method.
Now that we have created our NavigationConfirmationInterface object, we need to tell the application to use it. To do this, we call the eventbus method, setNavigationConfirmation. By default, no confirmation is set so all navigation events will be confirmed and fired. Also, you can only set one NavigationConfirmationInterface at a time for your whole application.
The next question we have is when do we set our NavigationConfirmationInterface? Usually the best time to set it is when it's associated presenter becomes active (ie when this presenter handles the place event). Thus, when handling the place event, we call the setNavigationCommand method.
We have now setup the Navigation feature. Its first goal is to obviously control users' navigation but it is actually a lot more powerful as you can realize any action you need when the user goes to a new place.
In the next posts, I'm going to continue covering advanced Mvp4g features related to history and navigation by describing the hyperlink token generation feature and the custom place service feature.
To demonstrate this feature, I'm going to reuse the example developed for the previous tutorial and add a form on page 2. You can download the example here (Project: Mvp4g_Navigation_Control).
Adding a form to our example
This form is pretty simple with only two fields (first and last name) and a save button.
We have the following screen:
public interface IPage2View extends IsWidget, LazyView {
public interface IPage2Presenter {
void onSaveClick();
}
HasValue<String> getFirstName();
HasValue<String> getLastName();
...
}
When displaying page 2, we update the values displayed on the screen with the local variable value and inversely when clicking on save.@Presenter( view = Page2View.class )
public class Page2Presenter extends LazyPresenter<IPage2View, NavigationControlEventBus> implements IPage2Presenter {
private UserBean user;
...
public void onGoToPage2( String origin ) {
...
view.getFirstName().setValue( user.getFirstName() );
view.getLastName().setValue( user.getLastName() );
eventBus.setBody( view );
}
@Override
public void onSaveClick() {
user.setFirstName( view.getFirstName().getValue() );
user.setLastName( view.getLastName().getValue() );
view.alert( "User Info saved." );
}
...
}
Now that we have set our form, we need to check that, when the user leaves the page, he doesn't lose any data.Defining navigation events
The first questions we need to answer are what does it mean to leave a page and when does it occur? In the GWT world, we have a single page application so we can't consider that a user goes to a new page when it loads a new HTML file. Instead the notion of places has been introduced. A place defines where the user is in the application. So leaving a page means going to a new place.
In Mvp4g, you go to a new place by firing an event. Thus the first step to control user navigation is to indicate which event brings the user to a new place.
In order to do this, a new attribute has been added to the @Event annotation, 'navigationEvent'. If set to true, it indicates that when this event is fired, the user is brought to a new place. In our example, we have two place events, goToPlace1 and goToPlace2.
@Events( startView = RootView.class, historyOnStart = true )
public interface NavigationControlEventBus extends EventBusWithLookup{
...
@Event( handlers = Page1Presenter.class, historyConverter = PageHistoryConverter.class, name = "page1", navigationEvent = true )
void goToPage1( String origin );
@Event( handlers = Page2Presenter.class, historyConverter = PageHistoryConverter.class, name = "page2", navigationEvent = true )
void goToPage2( String origin );
}
Whenever one of these events is fired, a control will be performed if a navigation confirmation has been set. This control will also be performed whenever the history token changes.Creating a navigation confirmation
Now that we have configured our navigation events, we need to create a navigation confirmation to control the navigation. In order to do this, we need to create a class that implements NavigationConfirmationInterface. This interface defines the following method:
void confirm( NavigationEventCommand event );
This method is called whenever a navigation event is fired or if the history token changes. It takes one parameter, a NavigationEventCommand that represents the event. As you may have noticed, this method is asynchronous, which means that it doesn't return a boolean to confirm the event or not. Instead, the method is in charge of confirming the event by calling the fireEvent method of the NavigationEventCommand parameter (if you don't want to confirm the event, you just don't call this method). Why is this method asynchronous? Mainly for two reasons:- You may want to call services when confirming your event (to save data before going to a new page for example).
- You may want to use your own custom confirm popup. Since it is asynchronous, you can easily block any other action until the user answers the question.
To create a NavigationConfirmationInterface, I usually have the presenter implement it directly. This way, I can easily have access to the data and the view to confirm the navigation and I limit the number of classes.
In our example, we want to control that data entered in the form has been saved. In order to do this, we just check if the data displayed in the view matches the data of the local variable. If it doesn't, we display a message to the user using the default browser confirm popup. If data matches or if the user wants to leave the page anyway, we confirm the event by calling the fireEvent method.
@Presenter( view = Page2View.class )
public class Page2Presenter extends LazyPresenter<IPage2View, NavigationControlEventBus> implements IPage2Presenter, NavigationConfirmationInterface {
...
@Override
public void confirm( NavigationEventCommand event ) {
boolean sameData = user.getFirstName().equals( view.getFirstName().getValue() ) && user.getLastName().equals( view.getLastName().getValue() );
if ( sameData || view.confirm( "Data not saved, are you sure you want to leave the page?" ) ) {
event.fireEvent();
}
}
}
Setting a navigation confirmation
Now that we have created our NavigationConfirmationInterface object, we need to tell the application to use it. To do this, we call the eventbus method, setNavigationConfirmation. By default, no confirmation is set so all navigation events will be confirmed and fired. Also, you can only set one NavigationConfirmationInterface at a time for your whole application.
The next question we have is when do we set our NavigationConfirmationInterface? Usually the best time to set it is when it's associated presenter becomes active (ie when this presenter handles the place event). Thus, when handling the place event, we call the setNavigationCommand method.
@Presenter( view = Page2View.class )
public class Page2Presenter extends LazyPresenter<IPage2View, NavigationControlEventBus> implements IPage2Presenter, NavigationConfirmationInterface {
...
public void onGoToPage2( String origin ) {
//set the presenter to control the navigation when its view is being displayed
eventBus.setNavigationConfirmation( this );
...
}
...
}
Another question you may have now is that if I set a NavigationConfirmationInterface whenever the presenter becomes active, shouldn't I remove it whenever the presenter becomes inactive (ie whenever the user goes to another place)? This is actually done automatically for you. Whenever you confirm an event by calling the fireEvent method of the NavigationEventCommand, this code is executed:eventBus.setNavigationConfirmation( null );
This code unsets any NavigationConfirmationInterface instance. If for some reason, you don't want this to happen, instead of calling:event.fireEvent();
you can use:event.fireEvent(false);
What's next?
We have now setup the Navigation feature. Its first goal is to obviously control users' navigation but it is actually a lot more powerful as you can realize any action you need when the user goes to a new place.
In the next posts, I'm going to continue covering advanced Mvp4g features related to history and navigation by describing the hyperlink token generation feature and the custom place service feature.
Subscribe to:
Posts (Atom)
