0

I think there is a limitation to the usage of a tag handler: a tag handler cannot be safely added to a c:forEach tag.

I can understand that this type of construct may look strange, but I faced a situation where the number of custom changes made to a component had to be dynamic, as in the follow example:

<my:component ...>
    <c:forEach items=#{bean.items} var="item">
        <my:tag ... />
    </c:forEach>
</my:component>

This construct does not work in a postback if the number of items changes.

  • During the restore view phase, the number of items is equal to the number of items that was rendered in the previous response. In this phase, the parent component of the tag handler is new.
  • During the render response phase, the number of items may have changed if, for instance, the bean model has been updated since the previous render response phase. During this phase, when in a postback, the parent component of the tag handler is not new.
  • As we don't want to apply the same changes twice to the parent component (restore view, and render response), we first check whether the parent component of the tag handler is new, and we apply the tag if and only if it is new.
  • But in that case, during a postback, the changes that are applied to the parent component are not those specified by the bean after is was updated, because in the render response phase the parent component is not new anymore.

I'm not sure there is a simple solution to this use case, and maybe should I use a component instead of a tag in that case?

Remark:

  • In the restore view phase, the tag handler applies the changes to its parent component.
  • Then the state of the parent component is restored.
  • If the changes applied to the parent component were saved in component's state holder, then these changes are restored after the tag handler is applied.
  • Therefore, during the restore view phase, these changes are first applied by the tag handler and then replaced by those that were saved. Looks redundant, no?

Possible workaround?

I've tried a workaround that seems to work in the case where the changes applied to the parent component only concern the way it is rendered:

  1. Apply the tag to the parent component only in the render response phase, no matter if the parent component is new or not.
  2. Do not save the changes applied by the tag into the parent's component state holder.

Of course this approach does not work if the applied changes had to be use between the restore view phase and the render response phase.

Stéphane Appercel
  • 1,427
  • 2
  • 13
  • 21

0 Answers0