net

AJAX Web Framework Architecture

Architecture of the Web Framework

User actions

Every client-side component can trigger component specific events. Every event is triggered on the parent form component by calling jasty.raiseEvent method (see click handler in the Button-component). The "raiseEvent"-method makes an AJAX-submit including event handler name, event parameters and the whole form data. All AJAX-submits are sent to a central Form Engine URL

The submit is then processed on the server by the Form Engine, which retrieves request parameters, restores the stateful presenter (Form) and calls the specified event handler method.

The classical submits are obsolete and not used anymore. AJAX form submits can do all the same things and doesn't require the page to be completely re-rendered.

Forms

In the classical MVC/MVP frameworks, actions don't share any data between requests by design. It may make those frameworks slim, fast and easy to use for building dynamic web sites, but doesn't facilitate the modelling of rich client applications.

In a rich client application, life cycle of a view can span a number of actions, each working on the same data context. Thus, view object could be modelled by a POJO with the instance fields as the data context and with the methods as event handlers. Such view object is very similar to a classical controller/presenter, except for being stateful. We call such view object a Form.

Form state on the client

The next question is how to maintain Form object between requests. Keeping it in session, like some frameworks do, is not a particularly good idea, because of the memory and scalability issues. A slightly better alternative is to keep it on the client.

When rendering the Form's main view, the Form-object gets serialized and sent in the response to the browser. Client-side form component keeps serialized Form and jasty.raiseEvent posts it back along with the other data. Form Engine on the server side deserializes the Form and calls the appropriate event handler method.

Event handlers

Event handlers are instance methods of the Form-class. The name of the handler to be called is posted back to the server on user action, along with the serialized Form object, form data and event parameters.

Event handlers contain business logic and interact with the client side via proxy components.

    public class TestForm extends Form {
        private int numberClicked;

        public void buttonClicked(EventArgs e) {
            Button btn = get(Button.class, "someId");
            numberClicked++;
            btn.setText("I'm clicked "+ numberClicked + " time(s)");
        }
    }

Event handlers may also use and modify Form instance variables. The Form-object gets serialized at the end of every request and sent with the AJAX-response to the client, so that the object can be exactly restored to handle subsequent events.

Form Views

Every Form always has one associated main view. This view gets rendered when the Form has to be visualized. Every main view is implicitly rendered within its own form component, which is responsible for providing necessary context for every event. Method prepareModel of the Form is used to obtain the model for the main view.

Apart from the main view, partial views can be defined for a Form. These partial views can be rendered on actions and used to dynamically overwrite particular fragments of the main view.

Finding and rendering of the views depends on the underlying template technology and is bridged by the Form Engine.

Client-side components and proxies can be bound into the views by implementing custom tags. Custom tag typically renders some HTML code (an outer tag or a placeholder tag) and javascript initialization for the component.

Underlying Form-object serves for the associated views also as a naming provider. It automatically ensures uniquity of the component ids to avoid clashes in case of several simultaneous Forms displayed.

Object-based navigation

Since Form-class together with the views represents a cohesive and stateful unit, Form object can be directly used for navigation within the web application. For instance, every Form can replace itself with another form:

    public void detailsClicked(EventArgs e) {
        replaceWith(new DetailsForm(e.get("data")));
    }

Another important scenario is the modal navigation in inline and popup modes.