Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Latest commit

 

History

History
160 lines (102 loc) · 11.1 KB

concepts.md

File metadata and controls

160 lines (102 loc) · 11.1 KB

LaxarJS Concepts

In order to get productive with LaxarJS, a basic understanding of a few core concepts is helpful.

A LaxarJS Application

To the visitor running a web browser, an application is a set of URLs and associated pages which are loaded by the browser to provide some information or functionality. An application may access web services or connect to database programs, which are not considered part of the LaxarJS application itself.

From a developer point of view, an application primarily consists of:

  • a set of LaxarJS widgets and activities providing the functionality
  • the pages and layouts assembling these widgets and activities
  • a flow that connects the individual pages
  • one or more themes to define the look and feel of the application.

In order to run the application, there are additional secondary resources:

  • the LaxarJS runtime loads flow and pages, sets up the widgets and connects them to the event bus
  • controls which are used by the widgets to provide advanced user interface functionality, such as those provided by LaxarJS UiKit
  • libraries used by widgets and activities, such as moment.js, jQuery, and LaxarJS Patterns.

The following two sections first explain the primary application components, and then the underlying secondary components.

Primary Application Parts

Widgets

A LaxarJS widget is a rectangular part of the browser viewport which allows the user to perform some task. It usually consists of several HTML elements, but might in some cases use only a single element, for example a canvas to provide a painting surface.

The important distinction between a LaxarJS widget and a plain HTML control (such as a select box or an input field) is that a widget is written with a specific user-goal in mind, whereas a control is general-purpose and its role in the application is up to the developer. For example, while a control might allow a user to input some text (such as a name, or a password), a widget might combine these input controls in a box to allow the same user to log in to the application, and another widget might allow the user to register a new account. So, both widgets and controls are parts of the user interface, but on different levels of abstraction.

To illustrate this with further examples, possible widgets with their specific goals include:

  • a to-do list, to check and plan what is to do
  • a shopping cart, to review and edit purchase items
  • a route planner displayed as a map, to plan a journey
  • a calendar displaying various events, to schedule and check appointments
  • the details editor for a specific event, to reschedule or cancel an appointment
  • a social buttons bar, to share content.

In contrast, these are controls:

  • an input field, to display/edit any text
  • a date picker, to display/edit any date
  • a select box, to choose from any list of options
  • an accordion control or a tab control, to navigate any set of contents.

Another way to think of it is that widgets are made of controls, and controls are HTML elements which may be user-defined (for example through AngularJS directives). The program logic of an individual widget is implemented in JavaScript (as an AngularJS controller) while the presentation is defined as an (AngularJS) HTML template, optionally accompanied by CSS styling information. Another important property of widgets is that they always can be loaded and tested in isolation. A widget instance may be put onto any page, regardless of what other widgets (even of the same type) might already be there.

Activities

A LaxarJS activity is a widget without a visual representation, performing a task for the user behind the scenes. To build upon the previous example, a login widget might talk to an authentication service itself, but it might also delegate this task to an authentication activity using the event bus. When the authentication mechanism changes (e.g. from a plain HTTPS login to OAuth) only the activity needs to be exchanged, while the widget might remain untouched. In contrast to libraries and regular AngularJS services, activities participate in the lifecycle of the page and are attached to the event bus, which allows them to communicate with other widgets using publish/subscribe.

Another possible example would be a web search widget offering a search box with a list of web search results. Instead of hard-wiring the widget to a specific search engine, one could implement multiple engine-specific activities and choose depending on user preference. Because the search widget does not know any of the activities (it just subscribes to the search results) one could even define a "proxy" activity to combine results from multiple searches without touching any of the other implementations.

Another way to think of it is that widgets have to run in the browser, while activities might run in any JavaScript environment. In contrast to visual widgets, activities do not have HTML templates nor CSS styles. To sum it up, widgets support direct user-interaction, while activities perform tasks behind the scenes, such as talking to (REST) services or coordinating different widgets.

Pages

A LaxarJS page combines and configures widgets and activities that should be displayed together by embedding them in an HTML skeleton (the layout). When navigated to, the runtime loads the page and puts the widgets referenced by the page into the associated layout to display them. The page also defines the publish/subscribe topics that the widget instance use to communicate resource state and user actions.

An individual widget is still somewhat generic in that it allows to perform a specific task in any context. For example, a social buttons bar might allow to share any content, and the specific list of social sites to share on might be configurable. The page establishes this context, for example by placing the social buttons below a news article (rendered from markdown by another widget), and by configuring that twitter and tumblr should be offered, but not LinkedIn. This does not mean that all widgets must be broadly reusable: a widget to manage the inventory in a video game would probably not be useful anywhere else. But it means that reuse is supported for those widgets where it makes sense.

While widgets and activities are implemented in JavaScript and HTML, pages are written using JSON in a declarative fashion. This reflects on the fact that pages do not contain application logic, but merely assemble and configure a set of widgets. Usually, each page occupies its own "screen" in your application, but there are mechanisms to divide pages into fragments and to compose them back together.

Layouts

LaxarJS layouts are skeleton HTML documents, which contain placeholders (called widget areas) within which widget instances can be placed. Each page specifies a layout that the LaxarJS runtime should use for it. A layout can contain all the scaffolding markup of your application (such as copyright footers and navigation), but you may also choose to implement these areas as widgets to allow for re-use and configuration.

For each widget areas, the layout defines a width in grid columns, and widgets within these areas may not exceed their available number of columns. The LaxarJS UiKit ships with Bootstrap to implement the grid layout in CSS. Like widgets, layouts are accompanied by CSS styles, for example to define a background color.

You might think of layouts as the opposite of activities: While activities are just widgets without a user interface, layouts are similar to widgets without the logic part – just HTML templates and CSS.

The Flow

The flow defines URL patterns that may be used to navigate to the pages of an application, and relations between pages. It is comparable to the routing mechanisms found in many MVC web frameworks. Also, the flow defines semantic relations between pages, such as what is considered the next page from a given page in the application.

Themes

Widgets and their controls may be styled using CSS. For widgets with a broad applicability (such as a calendar, or a route planner) it can be very useful to adapt the visual appearance to various circumstances. This is achieved by overriding parts of the vanilla bootstrap CSS classes (shipping with LaxarJS UiKit) with user defined CSS styles. A theme may specify styles for any control and for any widget that it wants to modify. Where nothing else is specified, plain bootstrap is used.

The LaxarJS UiKit is based on Compass/SCSS to simplify the generation of user defined themes. However, any way to generate Bootstrap-like CSS styles is a valid way to create a theme.

Secondary Application Parts – Under the Hood

The LaxarJS Runtime

The runtime handles URL routing and loads the template associated with the current page definition. It instantiates all required widgets and activities, and tells them when everyone else is ready to receive their publish/subscribe-events. It also loads the corresponding templates and CSS files, or provides these assets from an optimized bundle in production. Once everything is set up, the runtime gets out of the way: it lets the widgets perform their tasks and communicate through the event bus as needed.

The LaxarJS Event Bus

The event bus allows widgets to talk about common topics, without knowing anything about each other (not even a service name, interface or super-class). Widgets may request actions (such as a navigation or saving the page state), and other widgets might be there to respond to these actions. Likewise, widgets might provide resources (JSON structures), or expect resources to be provided for them. Because each widget uses its own isolated copy of the relevant resources which is synchronized over the event bus at well defined instances, race conditions are effectively avoided.

Controls

Controls are (user-defined) HTML elements and attributes, usually implemented as AngularJS directives. They are available to widgets as reusable UI components, and are styled using Bootstrap 3.2 for interoperability and theme support. A useful set of controls to get started is provided by the Angular UI Bootstrap project.

Libraries

Widgets may use libraries such as jQuery or moment.js just like in any JavaScript web application. LaxarJS currently provides a development workflow based on grunt, bower, and RequireJS in order to install and load widgets with their assets as well as libraries, but other tool-chains are not out of the question.

To establish a useful common base vocabulary for use with the event bus, the LaxarJS Patterns library is provided. It contains helpers that make it easy for widgets to talk about user actions, common (REST) resources and boolean flags.

Next Steps

After this quick tour through the building blocks of a LaxarJS application, have a look at the manuals for in-depth information on individual topics.