UI Framework – jMaki
Features
- Ajax in a tag - jMaki wraps Ajax components into easy to use tags.
- Normalize JavaScript toolkit APIs - jMaki has a single widget mode that wraps other APIs and can provide a standardized way of representing, documenting, and tooling widgets. In other words re-usable widgets can be created from various libraries where we can pick and choose which is best for our needs.
- Server Integration - jMaki uses the server frameworks to accelerate and enhance the JavaScript experience by providing a way to use PHP, Java, or JavaScript on the server and have the correct data accessible to our jMaki widgets. jMaki doesn't prescribe a specific server data model but can be integrated well with existing environments.
- Composition Support - jMaki provides a mechanism for page composition to enable the programming model know as the page as the application. All containers widgets such as the tabbed views and accordions provide the built in support for this model using an API called the Injector. This API is also available for reuse in our own widgets.
- Standardizes Data Model - jMaki provides a common data model. It allows for many structures such as trees, tables, tabbed views, and accordions to be described in JavaScript Object Notation (JSON) format. Widgets from different toolkits can be used with the same data.
- Unobtrusive JavaScript - jMaki provides publish/subscribe mechanism for inter-widget communication and a glue mechanism which allows us to define application specific behavior outside of the markup.
- External Service Integration - JavaScript can not directly access content outside of the domain using XMLHttpRequests because of browser security constraints (which is a good things). jMaki provides a generic XMLHttpProxy for tying in external services in a generic way. Examples provided include Yahoo Geocoder Flickr Search, and RSS integration.
- Layout Templates - CSS may and should be used to provide a layout for a web application. jMaki provides a set of layouts which may be used as templates for your web pages. These layouts may be easily customized and promote proper web design.
- Designer Friendly - Not all toolkits promote a designer friendly way of web application design. jMaki promotes a clean separation of CSS/JavaScript/HTML.
- Ajax Tooling Support - jMaki provides meta data for all widgets in a friendly manner where the tool enhances jMaki development. jMaki applications also can be designed outside of a tool.
- Multi Server Support jMaki currently supports JSF/JSP/PHP/JavaScript. Other environments are planned (a certain gem-related language is being prototyped).
The jMaki Widget Model
A jMaki widget is a reusable component that is made up of an
HTML template and a corresponding JavaScript file. An optional CSS file may be
provided by the widget. This document details the jMaki widget model and what
initialization parameters that are passed to each widget.
Template - component.htm
jMaki ensures that the HTML templates get rendered with unique
and instance specific parameters. The following is a template of a simple
<div> element with unique id.
<div id="${uuid}"></div>
component.htm Example
The
${uuid} token is replaced when
jMaki processes the template as it renders the page. Behavior - component.js
jmaki.namespace("jmaki.widgets.foo.bar");
jmaki.widgets.foo.bar.Widget = function(wargs) {
// widget code here
}
component.js example
Notice that the entire widget is placed in a namespace
jmaki.foo.bar and that it is called "Widget". This is because all jMaki widgets are
in essence packages and the Widget is the constructor
which is passed an the widget arguments. Widget JavaScript code not conforming
to this convention will not be loaded. Widget Properties
The server-side runtime passes instance parameters for an
individual widget to the jMaki JavaScript runtime as a function call with the
instance parameters as an object literal. The JavaScript runtime then passes
instance parameters to the widget as it is created. Following are the arguments
that are passed and the token names that are replaced in the widget
component.htm template.
|
Property Name
|
Template Token
|
Widget Arguments
|
Value
|
|
script
|
N/A
|
N/A
|
The URI to JavaScript for the widget.This is basically
an override for the
component.js. |
|
template
|
N/A
|
N/A
|
The URI to the template.This is an override for the
component.htm. |
|
style
|
N/A
|
N/A
|
The URI to the styles used for this widget.This is an
override for the
component.css. |
|
name
|
${name}
|
wargs.name
|
The name of the component. This is the only required
argument.
|
|
id
|
${uuid}
|
wargs.uuid
|
The unique value associated to each component instance.
This value is autogenerated by the server runtime and may be overriden using
an 'id' argument.
|
|
args
|
${args}
|
wargs.args
|
A JavaScript object literal that may contain any number
of JavaScript key value pairs.
|
|
service
|
${service}
|
wargs.service
|
This is the service value associated with each component
instance. When a service is used, the data used by the widget is loaded
asynchronously using an Ajax
call after the widget has loaded.
|
|
value
|
${value}
|
wargs.value
|
The service value is an inline value given to the widget
that needs to be in JavaScript object literal format.
|
The most powerful attribute is the
args attribute as it can be used to map any set of
generic properties to a widget as an object literal. These properties may then
be accessed from the widget instance (via the widget.args property). Care must be taken to properly
document the various properties as they can differ on a widget to widget basis.
With JSP and JSF, the properties are passed in using tag
attributes on the tag matching the name of the property. In all cases the
properties must be included in double quotes. All JavaScript properties used
with the
args and value are JavaScript object literals and should use single quotes
or escaped double quotes.Widget Initialization
jMaki will do the following after the page
onload event fires. - Lookup
up the constructor function for each widget in the order they are defined
in the page. Constructors must be named jmaki.[widget name].Widget. For
example, in the case of a widget with the name "foo.bar" the
constructor that is searched for is
jmaki.widgets.foo.bar.Widget. Note that all constructors are required to be under thejmakinamespace to keep all jMaki JavaScript objects from cluttering the JavaScript global scope. - Call
newon the constructor passing the widget instance parameters as an object literal. - Place
the widget instance contained in the
jmaki.attributes Mapwith the unqiue ID (uuid) as the key. You can later get a handle of this widget instance using the calljmaki.getWidget(uuid)
Post Load Event
If your widget requires post initialization you can provide a
postLoad function which will be called following the
widget initialization. // define the namespaces for foo and bar
jmaki.namespace("jmaki.widgets.foo.bar");
jmaki.widgets.foo.bar.Widget = function(wargs) {
this.postLoad = function() {
var this = jmaki.attributes.get(wargs.uuid);
// do something with this
}
}
component.js example with a
postLoad function
Providing a public
postLoad is a good place to
register glue
listeners and load data asynchronously. Widget Destruction
You can provide a code that will unwire events and nodes that
may lead to memory leaks by providing a
destroy function on your
widget. This function will be called when the clearWidgets function is called. // define the namespaces for foo and bar
jmaki.namespace("jmaki.widgets.foo.bar");
jmaki.widgets.foo.bar.Widget = function(wargs) {
var container = document.getElementById(wargs.uuid);
this.destroy = function() {
var this = jmaki.attributes.get(widget.uuid);
// do something with this
}
}
component.js example with a
destroy function
While not required, it is recommended you provide a public
destroy method in your widgets to clean up widget resources.
The
life-cycle of a jMaki Widget
Now that we know what widgets are and have seen how widgets
names and types are used let's dig a little deeper and see how widgets are
created and initialized. jMaki widgets are rendered in a two step process which
spans both the client and the server. The following diagram details the
lifecycle in more detail.
- jMaki Widget Defined Encountered
- Resource
References for the Widget are Rendered to the Page
- The JSP tag or JSF component renders the necessary HTML content with the
proper linkages to the corresponding files that make up a jMaki widget.
For example, the CSS styles defined in the
component.cssof a widget. If the widget is of a specific type, such as Dojo, the script tags for those dependent libraries will also be rendered to the page. - Template
Content is rendered to the Page - The template content
from the
component.htmfile is rendered to the page. The template content contains tokens such as${uuid}which represent a unique identifier of the widget. These identifiers are replaced on a per widget basis as the HTML is initially rendered. Content will be further rendered on the client after the page loads. - jMaki Bootstrapper is Initialized - A script element containing the jMaki boostrapper (jmaki.js) is rendered to the page before any other script references are rendered by the JSP tag or JSF component. This script creates a globally scoped JavaScript object named "jmaki" which contains properties and functions to register, load and support jMaki widgets.
- Widget
instance is created and registered with the Bootstrapper
- After a widget's template text has been rendered, the widget along with
its instance parameters is registered with the
jmakibootstrapper. Registration is done using thejmaki.addWidgetfunction where the instance parameters used to initialize the widget are passed as object literals. - Widgets
are Initialized and Rendered to the Page - Following the
JavaScript "onload" event the
jmakiboostrapper will iterate through the widgets that were registered and initialize each instance. Each widget is evaluated using the JavaScript code from the correspondingcomponent.js. A locally scoped object literal namedwidgetcontaining the initialization parameters (properties) for the widget such as the the unique identifier of the widget, service name, and arguments that were defined for the widget is used to initialize the widget instance. These parameters correspond with those that were rendered to page for that widget instance. - The Page is made available - Once rendered, the page is made available for further event processing.
The key steps for the the parameters getting passed by the
server rendered code to the JavaScript instance are found in steps 3, 5 and 6
above. Parameters such as the widget identifier from template content in
component.htm are rendered in step 5 and are passed to the
JavaScript runtime (the jmaki.addWidget bootstrapper). The
same parameters are then passed as properties in step 6 to the component.js script that initializes the widget instance.
jMaki is all about parameterized JavaScript. Now that we have seen how the
parameters are passed between the Java and JavaScript worlds lets look in more
detail at what parameters may be passed.
No comments:
Post a Comment