Skip to content

v1 02. Components

Frank Hossfeld edited this page Nov 28, 2019 · 1 revision

Components

Application Interface

The application interface provides basic information about the application. It has to extend IsApplication and be annotated with Application.

The Application annotation defines:

  • loader: defines the loader class, which will be called at application start (this parameter is optional)
  • startRoute: the route, which will be used, in case the application is called without a bookmark
  • context: context of the application
  • routeError: the error route is used to show an error page if Nalu detects some issues
  • useHash: if true Nalu uses a hash token, otherwise a hashless token. (default: true) - since v1.1.0
  • useColonForParametersInUrl: if true Nalu uses a ':' before a parameter inside the url (default: false) - since v1.1.0

An application interface might look like this one:

@Application(loader = MyApplicationLoader.class,  // is optinal
             startRoute = "/application/dashboard",
             context = MyApplicationContext.class,
             routeError = "errorShell/error")
interface MySimpleApplication
 extends IsApplication {
}

Shells

The Shell annotation defines a shell and is used on on a class that extends IsShell:

The Shell annotation has one value:

  • value: name of the shell (to be used at the start of a route)
@Shell("applicationShell")
public class ApplicationShell
    extends AbstractShell<MyContext> {
  ...
    }

Entrypoint

The EntryPoint is the start of your application (in case you are using GWT 2.x). To start the application you have to add the following lines:

 public void onModuleLoad() {
    // Create the application.
    // The ApplicationImpl-class will be generated by the framework.
    MySimpleApplication application = new MySimpleApplicationImpl();
    // start the application by calling the run()-method.
    application.run(new NaluPluginElemental2());
  }

Nalu needs to know which Nalu plugin (currently available are a GWT- and a Elemental2-plugin) the project would like to use. This is done by setting the instance of the plugin as a parameter of the run-method.

Context

The context can be used to store application wide information (f.e.: such as user name, etc). A instance of the context is injected in every filter, handler and controller. This is a good place to store general needed data.

Component

The component contains the visible part of a screen. It can be compared to the view of the MVP pattern. A component will be automatically created by the framework and injected into the controller. The use of the component class respects the view delegate pattern.

Controller

The controller can be compared with the presenter of the MVP pattern. It must be annotated with @Controller. The referenced component is created by the framework and injected into the controller.

A controller annotation may look like this:

@Controller(route = "/applicationShell/route01",
            selector = "content",
            componentInterface = IMyComponent.class,
            component = MyComponent.class)

The attributes of the controller annotation are all required.

The attributes are:

  • route: defines the route, which will make the component visible.
  • selector: defines the place inside the DOM where the component will be added.
  • componentInterface: is the reference to the component interface
  • component': is the reference of the component

A route '/[shell name]' indicates, that the controller will be executed at application start.

Parameters

In case the route has parameters, they have to be added to the route of the controller application:

@Controller(route = "/application/myRoute/:id",
            selector = 'content',
            componentInterface = IMyComponent.class,
            component = MyComponent.class)

To enable parameters, just add: /:parameterName at the route. It is possible to have more than one parameter. If a route contains a parameter, it is necessary, that the corresponding controller implements a method called: set[ParameterName](String value).

The type of the parameter is always String.

You can add as much parameters as you like. Every parameter has to Start with '/:'.

Controller Lifecycle

Every time a routing happens, a new controller will be created, the start- and active-method is called. Before the component will be removed from the DOM, the mayStop-method is called. This enables the application to interrupt the routing by returning a String value. In case a String is returned Nalu will display a confirmation dialog using this string.

In case a routing occurs, the deactive- and stop-method of the active controller is called before the start-method is called.

Nalu will never reuse a controller instance (except if you use caching!).

Eventbus

Every Nalu application has an eventbus. This enables the application to fire and handle events. The event bus is injected in every handler and every controller. So you can easily fire events and listen to them.

Nalu uses the event bus from the org.gwtproject.events artifact which is ready to use with j2cl.

Filter

To intercept a routing, Nalu offers filters. Filters can be used by adding the @Filter annotation to the application interface.

@Application(loader = MyApplicationLoader.class,  // is optinal
             startRoute = "/applicatiopnShell/application/dashboard",
             context = MyApplicationContext.class,
             errorRoute = "errorShell/error")
@Filters(filterClasses = MyFilter.class)
interface MySimpleApplication
 extends IsApplication {
}

A filter is triggered in case of a routing and will be executed before the routing occurs. It can interrupt a routing and redirect to another route. (f.e.: as a LogonFilter)

This is an example of a filter implementation:

public class MyFilter
  extends AbstractFilter<MyContext> {

  @Override
  public boolean filter(String route,
                        String... parms) {
    if (!user.isLoggedOn()) {
      return false;
    }
    return true;
  }

  @Override
  public String redirectTo() {
    return "/logon"; // route to 'logon'
  }

  @Override
  public String[] parameters() {
    return new String[]; // we have no parameters
  }
}

Handler

Handlers are classes without a component and can only be triggered by firing events. All handlers of a Nalu application will be created at application start. Handlers are great to deal with data, validate, etc. Usually handlers will catch events to get triggered. To give the control back to the application use a callback.

Loader (optional)

Nalu provides a loader that will be executed on application start. This is a good place to load static and meta data form the server.

Router

The router is the core of a Nalu application. It handles every routing of the application. The router is injected into every controller and handler. It enables routing inside the application.

Navigation is done by calling:

router.route("newRoute", [parameters]);

The router also provides a hash, so, that it can be used with anchors.

Caching

Nalu provides a caching mechanism. This allows to store a controller/component for a route. Next the route will be used, Nalu restores the cached controller/component instead of creating a new controller and component.

To tell Nalu to cache a controller/component, use the router.storeInCache(this)-command inside the controller. Now, caching for this route is active. To stop caching, call router.removeFromCache(this). To remove everything from cache, call router.clearCache().

Shell

A shell is the viewport of a Nalu application and will be placed into the browser window viewport by implementing the attachShell-method. The shell should contain selectors (id) where the childs will be added or Selector annotations depending on the chosen plugin.

An application can use several shells. A shell of an application is defined by using @Shell-annotation. To tell Nalu, which shell should be used for a route, use the shell name as first part of the route. The example blow tells Nalu to use a login shell and a application shell.

@Application(loader = MyApplicationLoader.class,  // is optinal
             startRoute = "/loginShell/login",
             context = MyApplicationContext.class,
             errorRoute = "/errorShell/error)
interface MySimpleApplication
 extends IsApplication {
}

Example for a shell class:

@Shell("applicationShell")
public class ApplicationShell
   extends AbstractShell<NaluLoginApplicationContext> {

 ...

}

To route to the login page (using the login-shell) will look like that:

'/loginShell/login'.

The route to a application component will look like that:

'/applicationShell/applicationComponent'.