• No results found

3.2.3 Implementation of object - URL mapping

We will look at the implementation of mapping URLs to instances. This task is done by an instance of Aida::URLResolver. This class holds list of these mappings. Mappings are simply associations, or key - value pairs, where key is URL address and value is a reference to instance. Important thing is that a mapping is added to the URLResolver during rendering of page where a link to this instance is present. This means, that it is not possible to access this object by URL before a page with reference to it had been rendered by Aida.

It is important to consider whether this behaviour is correct or not. If not, it is possible to create a subclass of URLResolver and to use it in our site. This subclass could use standard mapping algorithm, but if no appropriate record was found, it could try to search some predened collections for instance with requested preferred URL.

3.3 AJAX support

AJAX4 is in short a technology that allows JavaScript functions to send HTTP requests to the server, handle its response, and accordingly update the state of displayed document.

Sometimes there is a need to update our model object and to show its changed presenta-tion, the web page. If only a small part of the page changes, it is quite inecient to update the whole page. And this is exactly the situation where AJAX calls take their place.

Although the shortcut AJAX notes only XML, the server can respond with any format needed, a raw text, a fragment of HTML document, or a JSON string.

3.3.1 Common framework's features

As many frameworks have sophisticated methods for rendering HTML code, it is quite common to return a HTML code fragment when only one part of document is being updated, or an XML document that contains XHTML code fragments as sub-elements. The latter case allows JavaScript functions to update more elements with only one AJAX call (the IDs of elements should match).

It is quite common that modern frameworks isolates the developers from AJAX calls handling at all. There is no need to write JavaScript code or to create server side methods that handles AJAX calls, but developers just declare a request to be done over AJAX and everything else is almost transparent to them.

3.3.2 Aida's implementation

In the current release (6.0 beta 1) Aida supports updating content of one element only. It uses JavaScript library Prototype.js (see [Pro]), that oers some functions for cross-browser compatible AJAX calls.

As we mentioned above, using AJAX in a modern framework is quite transparent. For example, following simple code can be used to update a component after another component was clicked.

4Asynchronous JavaScript and XML

timeComponent

Figure 3.5: Aida - Simple AJAX element updating

anElement onClickUpdate: updatableElement.

The updatableElement can be identical to anElement. It is obvious that this construc-tion is not very useful when the state of our model has not changed. Good example for using this simple approach is showing current time. Methods in gure3.5 should be contained in a WebApplication subclass.

Before we continue to explain how to do update our model with AJAX calls, we have to know some details about the way AIDA updates old elements. Let's look at source code in picture3.5again.

Before a page is rendered, the whole component tree is created. Only some components (form elements, AJAX-updatable elements) are stored between user requests. But how the element returned by timeComponent knows how to update itself? It only knows that it contains a text element, but has no idea where the content of that text element has come from.

In fact, it knows a little bit more, to be specic it knows the name of method that has returned it in this case, it is symbol #timeComponent. This method is set automatically when a component is added to another component.

The problems is, that in some cases it is needed to replace the old element with a new one, and sometimes we need to update the content of the old element only, and not to replace it at all. Hence there are two ways to update a component:

• We can create our component in a WebApplication's method, and when Aida is han-dling an AJAX request that forces a component to be updated, old component is forgotten and new element is returned by that method (some actions are taken, so that the id of new and old element stay unchanged). This is the case we have used above.

• More complex way is to create new subclass of WebElement. There, we have to create a method, that is used to update the element after AJAX request. This method can

3.3. AJAX SUPPORT 19

take at most one string argument, so if we need to pass more parameters to it, we have to pack them into a single string. Last step is to set this method to be really called.

For this, we use method method of WebElement class. There is source code for creating a simple timer component in gure 3.6. It is worth noting that the component has to be wrapped into an HTML element (DIV, for example). That is why the setDiv method is used in the example.

"initialize method is called right after new component is created"

initialize

self id: self hash asString.

self setDiv.

self method:#buildTimerComponent:.

self buildTimerComponent:'Current time is '.

"this method is called when this component is going to be updated"

buildTimerComponent:aString

|e|self initElements; initTable.

self form: self app form.

self elements removeAll.

e := Aida::WebElement newDiv.

e addText:aString , ' ' , SpTimestamp now asRFC1123String.

self add:e.

e onClickUpdate:self with:'Updated time is '.

self app form registerFormElementsIn: self.

Figure 3.6: AJAX-updatable Aida component example

To be honest, non-standard AJAX calls is not very intuitive in AIDA. But there are some more problematic issues than this. We will discus them in the following section.

3.3.3 Known problems

There are some problems (maybe only features) that can bring serious diculties. They cause a bad element to be updated instead the one that should have been, or the one that the developer has expected to be.

3.3.3.1 Order of requests and responses

When two AJAX requests are sent to the server with too short delay between them, the response to the second request can arrive earlier than the response to the rst one. This is a problem, because only contents of a containing elements are updated, and there is no information that could be used for recognizing which response belongs to which request.

This is not directly Aida issue, this behaviour comes from Prototype.js JavaScript update method. To overcome it, we should use another way of updating elements, which would demand changes in both JavaScript code and Aida AJAX handling methods.

For now, we skip this problem, as it does not appear too frequently and can be reverted on client side by page reloading.

3.3.3.2 The way Aida searches for element to be updated

The previous problem could be classied as technical issue. This one is rather Aida design feature, that can make developers very upset be strange behaviour of AJAX updating. As we noted in section3.3.2, each AJAX updatable component knows the method that is used for updating itself.

But this method is not used only for actual re-building of the component, but also for identifying. If an old component is going to be replaced, it is searched by the building method. This means, that if two components have the same building method's name, they can be mistaken.

There are some ways that could help overcome this problem.

• Change some Aida core methods.

• Create subclass with overridden methods that cause this, and use this subclass. Over-ridden methods could do more sophisticated searching based on elements' ids instead on elements' building methods.

• Avoid invoking this method name-based searching, by proper manual setting of all IDs of AJAX-updatable components. This does not have to be possible under some circumstances.

Related documents