如何将参数传递给preRenderView事件侦听器

时间:2014-05-19 20:40:39

标签: jsf jsf-2 primefaces

我正在为preRenderView事件开发一个监听器方法,我打算拦截DOM树组件,并根据登录用户的权限将render属性设置为true或false。

我已经回顾了这些问题,但我仍有一些疑问

Set Bean property before listener

Safe Pass Parameters

这是我的主要模板的一个片段:

<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发送参数的正确形式是什么?。

1 个答案:

答案 0 :(得分:1)

问题

由于以下原因,您的各种尝试都失败了:

  1. 您正在错误的组件上应用f:attribute并尝试从辅助bean中的错误组件检索

    • f:attribute适用only on components that extend UIComponentjavax.faces.view.ViewMetadata未延伸UIComponent,因此f:attribute不适用于此String idForm = (String)event.getComponent().getAttributes().get("resource");

    • 加上以下一行

      ComponentSystemEvent

    上面的那一行看到你试图从javax.faces.event.ComponentSystemEvent实例获取属性,而不是你(错误地)试图将属性附加到

  2. 的元数据对象实例
  3. 与(1)相同,UIComponent不是<c:set/>的孩子

  4. 您已经知道第三种方法失败的原因。


  5. 解决

    当且仅当要设置的值在视图构建时可用时,JSTL的<c:set property="#{yourBean.property}" value="theValue"/> 才能正常

    {{1}}