我正在为preRenderView事件开发一个监听器方法,我打算拦截DOM树组件,并根据登录用户的权限将render属性设置为true或false。
我已经回顾了这些问题,但我仍有一些疑问
Set Bean property before listener
这是我的主要模板的一个片段:
<p:layoutUnit position="center">
<p:tabView id="tabItemList" scrollable="true"
activeIndex="#{borderTemplateMB.activeTab}">
<p:ajax event="tabClose" listener="#{borderTemplateMB.onCloseTab}" />
<c:forEach items="#{borderTemplateMB.tabList}" var="tabItem">
<p:tab closable="#{tabItem.closable}" id="#{tabItem.id}"
visible="tabItem.visible">
<f:facet name="title">
<span class="ui-icon #{tabItem.icon}" />
<p:outputLabel value=" #{tabItem.title}"></p:outputLabel>
</f:facet>
<ui:include src="#{tabItem.url}" />
</p:tab>
</c:forEach>
</p:tabView>
</p:layoutUnit>
内部或每个标签(.xhtml)我有这个内容:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:p="http://primefaces.org/ui">
<f:metadata>
<f:event listener="#{securityMB.doManageEvents}" type="preRenderView" />
<f:attribute name="resource" value="frm_groups" />
</f:metadata>
<ui:decorate
template="/protected/templates/#{customerMB.template}/forms/templateSearch.xhtml">
<ui:param name="tpl_panel_title" value="#{msg['panel.title.groups']}"></ui:param>
<ui:param name="tpl_title_filters"
value="#{msg['label.searchFilters']}"></ui:param>
相关部分是:
首先尝试
<f:metadata>
<f:event listener="#{securityMB.doManageEvents}" type="preRenderView" />
<f:attribute name="resource" value="frm_groups" />
</f:metadata>
在我的Request Scoped Bean中:
public void doManageEvents(ComponentSystemEvent event) {
UIViewRoot root = Faces.getContext().getViewRoot();
String idForm = (String)event.getComponent().getAttributes().get("resource");
LOG.info("[doManageEvents] Init " + idForm);
UIComponent comp = findComponent(root, idForm);
if (comp != null) {
printComponentTree(comp);
}
}
第一次尝试失败,因为属性“resource”未更新,始终显示第一个被调用的。
第二次尝试:
<f:metadata>
<f:event listener="#{securityMB.doManageEvents}" type="preRenderView">
<f:attribute name="resource" value="frm_groups" />
</f:event>
</f:metadata>
在第二次尝试时,资源属性为空。
第三次尝试:
<f:metadata>
<f:event listener="#{securityMB.doManageEvents('from_users')}" type="preRenderView" />
</f:metadata>
在我的Request Scoped Bean中:
public void doManageEvents(String idForm) {
UIViewRoot root = Faces.getContext().getViewRoot();
LOG.info("[doManageEvents] Init " + idForm);
UIComponent comp = findComponent(root, idForm);
if (comp != null) {
printComponentTree(comp);
}
}
这最后一种方法编译得很好和Works,但是eclipse在编辑器上显示了这个错误:
Method must have signature "void method(ComponentSystemEvent)" but has
signature "void method(String)"
我需要知道在编辑器上使用这种错误的方法。
向preRenderView Listener发送参数的正确形式是什么?。
答案 0 :(得分:1)
问题
由于以下原因,您的各种尝试都失败了:
您正在错误的组件上应用f:attribute
并尝试从辅助bean中的错误组件检索:
f:attribute
适用only on components that extend UIComponent
。 javax.faces.view.ViewMetadata
未延伸UIComponent
,因此f:attribute
不适用于此String idForm = (String)event.getComponent().getAttributes().get("resource");
。
加上以下一行
ComponentSystemEvent
上面的那一行看到你试图从javax.faces.event.ComponentSystemEvent
实例获取属性,而不是你(错误地)试图将属性附加到
与(1)相同,UIComponent
不是<c:set/>
的孩子
您已经知道第三种方法失败的原因。
解决
当且仅当要设置的值在视图构建时可用时,JSTL的<c:set property="#{yourBean.property}" value="theValue"/>
才能正常。
{{1}}