I have a legacy code that I am about to rewrite. It contains a lot of custom JSF components. Most of them simply builds a subtree of other components (either from JSF core or other customs) in place when they are in the tree. So for example in xhtml I have:
<custom-component atributes...>
<child-component/>
<child-component/>
</custom-component>
And then in PostAddToViewEvent implementation of this component does for example something like:
UIComponent rootChildElement = JSFUtil.findAncesstorOfType(this, HtmlForm.class);
List<UIComponent> guiListChildren = this.getChildren();
if (rootChildElement == null) {
rootChildElement = new HtmlForm();
} else {
rootChildElement = new UINamingContainer();
}
rootChildElement.getChildren().addAll(this.getChildren());
But during debugging I have noticed that when JSF processed an AJAX request for such custom component, that even though children are added to the created form, they are built again from XHTML page and added again. This results in those children being actually in two places in the tree when AJAX is performed.
Funny thing that this works in JSF 2.0.3, but when we wanted to upgrade to JSF 2.1.something it stopped working, because command link in the children which was AJAX source could not be found in the tree when it is expected to be.
I think it should be possible to do the same thing in PreRenderView phase, but then actions won't work, because command components will be created too late.
How such components should be implemented:
- composite component
- facelet tag
- tag decorator?
- something else?
Is it safe to modify component tree here? If I have a component, that do not reassign children, but adds some new items to itself like command buttons or other components?