AJAX Components - Part 3
AJAX Components - Part 3
This chapter is excerpted from Enterprise AJAX: Strategies for Building High Performance Web Applications, authored by David Johnson, Alexei White, and Andre Charland, published by Prentice Hall, © Copyright 2007 Prentice Hall. All rights reserved.
Building the Component
It is easiest to start by building the imperative version of the component and then enabling the use of a declaration to preset any component parameters. This approach is generally a wise one because it ensures a quality API from the point of view of an imperative developer, and it makes the component accessible to those that don't want to use the declaration. Let's look at how to build a declarative component for an application in which we want a list of Customers presented to a user that is populated from a server-side data handler using AJAX.
As a first requirement, we create our DataGrid control in the exact same way as any other instance of a class using the new keyword and pass the HTML element as a single constructor argument that refers to the element in which we want our component to be rendered in. However, as with any development effort, whether you use Extreme Programming or the Waterfall approach, we start by doing at least a bit of design up front. A DataGrid control can be represented fairly simply in a UML class diagram, as shown in Figure 4.3.
SimpleGrid class consists of a collection of column definitions, header and footer, and collection of rows. Furthermore, there are a number of methods that are inherited from the
Component class that are used by the declarative framework to instantiate, render, and destroy the component, such as
dispose(). There is a one-to-many relationship between the
SimpleGrid and the
Column class where the
Column class contains all the information needed to render a column of data such as the column header, footer, data, width, type, and CSS properties. Similarly, the
SimpleGrid class inherits from the Component class where all the requisite functionality for declaration parsing and templating is defined.
SimpleGrid constructor and
Component class look something like this:
SimpleGrid constructor, all we have done is create the three different template processors for the header, footer, and the data with some initial default templates. What happen to these templates is that the information from the DataGrid declaration merges with the initial templates to produce secondary templates. The advantage of doing this is that the declaration might not change during the lifetime of the component, yet the data is likely to change. With that in mind, after merging the declaration information with the templates, we cache the result so that we can reuse those generated templates as the data changes and make the tem-plating process much more efficient.
To instantiate an instance of the
SimpleGrid class based on an XHTML declaration, we use the following deserialize method, which also uses the generic deserialization method of the
Component base class:
SimpleGrid class, it copies over attributes from the
<ea:grid> XHTML element and then proceeds to search for any
<ea:column> elements that are then deserialized into
SimpleGridColumn objects also deserialize the declaration further to get information about the column header, data, and footer.
myGrid is the id of the declaration in the web page. To bring everything together and actually get the component to automatically deserialize, we use the same
initComponents() function we used when converting the Google Map to be a declarative component. All we need to do is create a factory method that is responsible for creating an instance of the
SimpleGrid class and put a reference to that method in the global hash table that maps XHTML element names to their respective factory methods:
Now, our DataGrid is still not rendering and it doesn't have any data to render. We can remedy this by adding the render method to the
SimpleGrid class that looks like this:
The render method takes the cached rendering templates that were created in the deserialization method and applies those generated templates to the data, which results in the contents of the DataGrid being generated after which that content is placed into the web page DOM using the
innerHTML property of the XHTML declaration element. The
dataSource field of the
SimpleDataGrid containing the data to be rendered can be populated simply by setting it to some static array of customer data like this: