RichFaces 4.0: Controlling AJAX updates for iteration compon
nbelaevski Oct 14, 2009 8:30 PMRichFaces contains several iteration components: sequential components (rich:dataTable, a4j:repeat, etc.) and hierarchical (rich:tree). For both of these families, it is important for the developer to have an ability to limit AJAX updates to certain row/tree node.
Currently in 3.3.x this problem is solved by "ajaxKeys" attribute that points to a set of row keys for which to do updates. Here is an example of this:
<rich:dataTable id="table" value="#{collection}" var="item" ajaxKeys="#{bean.ajaxKeys}"> <rich:column> <h:panelGroup id="group"> #{item.name} </h:panelGroup> </rich:column> </rich:dataTable> <a4j:commandLink value="Update" reRender="group" />
public class Bean { //... public Object getAjaxKeys() { Set keys = new HashSet(); keys.add(1); return keys; } //... }
Updates are controlled by two distinct components: data table defines which rows to update (using "ajaxKeys") and command link defines IDs of the components to update.
What is also sufficient is that output components with ajaxRendered="true" are also updated according to AJAX keys.
If AJAX keys are not defined, then set with a single implicit key (it is the key of the row in which AJAX event happened for this request) is used. If no implicit key for this table exists, then the whole value collection is being iterated (causing highly-voted JIRA issue: https://jira.jboss.org/jira/browse/RF-3341).
Also AJAX keys bound to session-scoped beans and not cleared after view is rendered can cause performance penalties due to excess updates.
The main problem of ajax keys approach IMHO is that control on AJAX updates is separated between two different view components. Considering the fact that we are going to let all components consisting of several tags be constructed using nested a4j:repeat, I believe that necessity of nested ajaxKeys for these cases should be simplified radically.
I think that another use-case that this approach doesn't cover is of very low importance and we can safely ignore it. That is the case of controlling updates for particular row components in a more agile manner, e.g. to update component "a" for rows 1, 3, 5 and component "b" for rows 1, 2, 3.
To solve this problem, the following form of notation is proposed:
render="form:table[12]:group" ...For me it seems to be a declarative and close to developer. However I see some problems with this approach:
- Ranges/sets of rows are hard to address, possible solution:
render="form:table[12, 13]:group"
- Complex keys (e.g. hierarchical) doesn't fit well in this scheme, because developer currently need to convert them to string manually using some sort of converter that guarantees safe bidirectional object-string conversion
Question for the case if we leave "ajaxKeys": do we need to add extra set of AJAX keys for auto-updated elements, e.g. messages updateable only in the processed rows?
General problems of updates by key - usage of data items as update keys can be a possible solution:
- Developer needs to know row keys, so this requires knowledge of how model creates them
- Defines only replacement/updates, not insertion/deletion. Also for standard sequential models (e.g. list-based) row key is not persistent, so this won't work correct with insertion/deletion