我正在为 preRenderView 事件开发一个监听器方法,我打算在其中拦截 DOM 树组件,并根据登录用户的权限将渲染属性设置为 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>
在我的请求范围 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);
}
}
第一次尝试失败,因为属性“资源”未更新,始终显示第一个调用的。
第二次尝试:
<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>
在我的请求范围 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);
}
}
最后一种方法编译良好并且有效,但是 Eclipse 在编辑器上显示此错误:
Method must have signature "void method(ComponentSystemEvent)" but has
signature "void method(String)"
我需要知道在编辑器上使用什么方法来处理此错误。
向 preRenderView Listener 发送参数的正确形式是什么?
最佳答案
问题
由于以下原因,您的各种尝试都失败了:
您正在应用
f:attribute
在错误的组件上并尝试从支持 bean 中的错误组件检索它:f:attribute
适用only on components that extendUIComponent
。javax.faces.view.ViewMetadata
不扩展UIComponent
所以f:attribute
不适用于它。加上以下行
String idForm = (String)event.getComponent().getAttributes().get("resource");
上面的行显示您尝试从
ComponentSystemEvent
获取属性实例,而不是您(错误地)尝试附加属性的元数据对象实例与 (1) 相同,
javax.faces.event.ComponentSystemEvent
不是UIComponent
的子项您已经知道了第三种方法失败的原因。
解决
JSTL的<c:set/>
当且仅当要设置的值在 View 构建时可用时才可以。
<c:set property="#{yourBean.property}" value="theValue"/>
关于jsf - 如何将参数传递给 preRenderView 事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23746827/