Dynamic <ui:include> doesn't work
I want to us开发者_StackOverflow中文版e a dynamic ui:include, like this.
<ui:repeat value="#{FormsService.getTemplates(component.form)}"
var="template">
<ui:include src="forms/#{template.id}.xhtml"/>
</ui:repeat>
Somehow this always results in an include of "forms/.xhtml", as if #[template.id} would be empty. But I know that #{template.id} is not empty. I.e. just printing it out like that gives me the expected value. So what goes wrong here? Any help is appreciated.
These tags are somewhat confusing since <ui:repeat> is implemented as a UIComponent and <ui:include> logic is in the TagHandler. When component tree is built, for example in restoreView phase, a single UIRepeat component is added but #{template.id} won't evaluate properly. It won't evaluate because UIRepeat variable "template" will be available only during component processing and not during tree construction.
You have got two options. The first is you can use <c:forEach> instead of <ui:repeat>. This is an easy solution and probably will work fine for you. There is one minor downside to it: if you have multiple occurences of the same template, the component tree will contain a separate copy of the template components for each occurence. As a consequence both memory and CPU performance will suffer.
The other option is to use a true dynamic include component. Unfortunately I haven't found one available. I managed to implement such component but it's not a very convenient solution since it also requires a slightly modified UIRepeat version. We had to go for this approach because the performance loss from <c:forEach> was too heavy for us.
精彩评论