在上下文中,我可以找到使用<ui:define>
构建的内容的信息吗?我想访问在我的bean中使用<ui:define name="title">Some title</ui:define>
定义的页面标题。
为了说明我的问题,我可以访问用
定义的变量<ui:param name="myVariable" value="This is my variable!"/>
通过查看EL上下文中的变量映射器,就像这样
VariableMapper variableMapper = elContext.getVariableMapper();
String myVariable = variableMapper.resolveVariable("myVariable").getValue(elContext).toString();
这适用于<ui:param>
,但是如何为<ui:define>
完成?
答案 0 :(得分:2)
这不可能通过标准API实现。 Xtreme Biker发布了一个绝妙的技巧,即&#34;默认&#34; <ui:param>
中指定了<ui:insert>
值,当Test if ui:insert has been defined in the template client
<ui:define>
时,该值将被覆盖(因此不存在)
(hacky)替代方案是为作业创建自定义标签处理程序。 <ui:define>
的名称是在Map handlers
后面的CompositionHandler
标记处理程序的<ui:composition>
字段中收集的。这是(不幸的是)具体实现,Mojarra和MyFaces有自己的实现,Mojarra将字段命名为handlers
和MyFaces _handlers
。
由于字段只是protected
,最简洁的方法是扩展CompositionHandler
代码处理程序类,并至少将apply()
方法中的密钥集公开为FaceletContext
的属性。但是,由于CompositionHandler
类本身已声明为final
,因此我们无法对其进行子类化。因此,我们无法将其作为代表包装,并使用一些反射hackery来获取该字段。
这里是一个基于Mojarra的启动示例,它收集了<ui:define>
中所有已声明的Map<String, Boolean>
处理程序名称,这样您就可以在EL #{defined.foo ? '...' : '...'}
#{not defined.foo ? '...' : '...'}
中很好地使用它们public class DefineAwareCompositionHandler extends TagHandlerImpl implements TemplateClient {
private CompositionHandler delegate;
private Map<String, Boolean> defined;
@SuppressWarnings("unchecked")
public DefineAwareCompositionHandler(TagConfig config) {
super(config);
delegate = new CompositionHandler(config);
try {
Field field = delegate.getClass().getDeclaredField("handlers");
field.setAccessible(true);
Map<String, DefineHandler> handlers = (Map<String, DefineHandler>) field.get(delegate);
if (handlers != null) {
defined = new HashMap<>();
for (String name : handlers.keySet()) {
defined.put(name, true);
}
}
}
catch (Exception e) {
throw new FaceletException(e);
}
}
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
ctx.setAttribute("defined", defined);
delegate.apply(ctx, parent);
}
@Override
public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException {
return delegate.apply(ctx, parent, name);
}
}
my.taglib.xml
1}}。
<tag>
<tag-name>composition</tag-name>
<handler-class>com.example.DefineAwareCompositionHandler</handler-class>
</tag>
在自定义<my:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:my="http://example.com/ui"
>
<ui:insert name="foo">
...
</ui:insert>
<div class="#{defined.foo ? 'style1' : 'style2'}">
...
</div>
</my:composition>
中注册以下内容:
{{1}}
您可以按照以下方式使用它:
{{1}}
同样,这是hacky(因为它的具体实现),我不建议使用它。