Jsf 如何访问使用<;创建的内容;用户界面:定义>;以编程方式?
在上下文中,我可以在哪里找到使用Jsf 如何访问使用<;创建的内容;用户界面:定义>;以编程方式?,jsf,facelets,Jsf,Facelets,在上下文中,我可以在哪里找到使用构建的东西的信息?我想访问在我的bean中用Some title定义的页面标题 为了说明我的问题,我可以访问用 <ui:param name="myVariable" value="This is my variable!"/> 这适用于,但如何适用于?这不可能通过标准API实现。Xtreme Biker发布了一个绝妙的技巧,即在中指定一个“默认”值,当实际指定为答案时,该值将被覆盖(因此不存在) 另一种方法是为作业创建自定义标记处理程序。通过其名称
构建的东西的信息?我想访问在我的bean中用Some title
定义的页面标题
为了说明我的问题,我可以访问用
<ui:param name="myVariable" value="This is my variable!"/>
这适用于
,但如何适用于
?这不可能通过标准API实现。Xtreme Biker发布了一个绝妙的技巧,即在
中指定一个“默认”值,当
实际指定为答案时,该值将被覆盖(因此不存在)
另一种方法是为作业创建自定义标记处理程序。
通过其名称收集在
后面的CompositionHandler
标记处理程序类的映射处理程序
字段中。不幸的是,这是特定于实现的,并且有自己的实现,Mojarra将字段命名为handlers
和MyFaces\u handlers
由于该字段仅受保护
,最干净的方法是扩展CompositionHandler
标记处理程序类,并至少将apply()
方法中的键集作为FaceletContext
的属性公开。但是,由于CompositionHandler
类本身被声明为final
,因此我们不能将其子类化。因此,我们不能把它包装成一个委托,并使用一些反射黑客来获取字段
下面是一个基于Mojarra的启动示例,它在映射中收集所有声明的
处理程序名称,这样您就可以在EL中很好地使用它们,比如so{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: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>
...
...
再说一次,这是黑客行为(因为它是特定于实现的),我不建议使用它
另见:
您到底想用它做什么?它基本上表示一个部分JSF组件树,而不一定是像ui:param这样的普通字符串。@BalusC:我只是想检查是否定义了名为title
的内容,如果没有,则设置一个通用页面标题。。我很好奇,这是如何通过编程实现的。我正在上下文中搜索带有键title
的组件树,但找不到它。好的,您基本上想检查
的
是否已在模板客户端中定义,而不管其内容如何?也就是说,您只对布尔值true
或false
感兴趣,这是基于您可以在模板中其他地方使用的布尔值?如果是这样,那么这是否可以接受为dupe@BalusC:页面标题应具有以下格式:AppName-PageTitle
。有些页面没有定义PageTitle
,而是将AppName
作为通用标题。有些页面确实如此,对于这些页面,定义的PageTitle
应与AppName
和dash
前缀连接。在我进行这项工作时,我尝试在bean中检索ui:define
的内容,以查看该信息在上下文中存储的方式和位置,但找不到它。我花了几个小时试图解决这个问题,但在网上找不到任何相关信息。任何正确方向的提示都是非常受欢迎的。@BalusC:您提供的链接对于这个问题来说绝对是一个可以接受的解决方案,但我对学习如何通过代码访问ui:define block很感兴趣。我现在明白了为什么我不能如此轻松地找到有关此问题的信息。非常感谢您提供了如此多的见解。
<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>