【问题标题】:Determine absolute id确定绝对id
【发布时间】:2012-10-02 10:30:40
【问题描述】:

如何确定 organizationUnit 的绝对 id(来自/webapp/resources/acme/organizationUnit.xhtml)?当我从树中选择一个节点时,organizationUnit 应该显示所选节点。我不能使用相对 id,因为 p:ajax 元素与 organizationUnit 组件不在同一个命名容器中。在这种情况下,我需要使用绝对 ID。使用 Firebug,组件的 id 是tabs:0:editorsGroup:4:editor3:accountWindowsContainer:organizationUnit:form:tabs:editorsGroup:editor:accountWindowsContainer:organizationUnit不是组件的绝对id吗?

编辑1

custom:include 配置如下:

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://acme.com/custom</namespace>
    <tag>
        <tag-name>include</tag-name>
        <component>
            <component-type>com.acme.custom.DynamicInclude</component-type>
            <handler-class>com.acme.client.custom.tags.DynamicIncludeHandler</handler-class>          
        </component>        
    </tag>   
</facelet-taglib>  

@FacesComponent("com.geneous.custom.DynamicInclude")
public class DynamicInclude extends javax.faces.component.UIComponentBase{ ... }

public final class DynamicIncludeHandler extends javax.faces.view.facelets.ComponentHandler { ... }

使用 Mojarra 2.0.8。

/WEB-INF/flows/actions-acc-flow/accounts.xhtml

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    template="/WEB-INF/layouts/standard.xhtml">

    <ui:define name="content">
        <h:form id="form" prependId="false">
            <!-- messages -->
        <p:growl id="msgs" showDetail="true" />
                 ...
            <h:panelGroup id="mainPanel">
                <ui:include src="/WEB-INF/flows/actions-acc-flow/genericAccountsTable.xhtml" />
            </h:panelGroup>
        </h:form>
    </ui:define>
</ui:composition>

/WEB-INF/flows/actions-acc-flow/genericAccountsTable.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

    <h:outputScript library="primefaces" name="primefaces.js" />
    <h:outputStylesheet library="primefaces" name="primefaces.css" />

    <p:dataTable id="genericAccounts"
    ...
    </p:dataTable>
    <p:spacer height="1" />
    <p:toolbar>
        <p:commandButton value="#{label.add}"
            action="#{accountsBean.initializeEntity}" immediate="true"
            update=":form:actionsDialog :form:msgs"
            oncomplete="actionsDialog.show()">                  
        </p:commandButton>              
    </p:toolbar>
    <ui:include src="/WEB-INF/flows/actions-acc-flow/mainDialog.xhtml" />
    ...
</ui:composition>

/WEB-INF/flows/actions-acc-flow/mainDialog.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

    <p:dialog id="actionsDialog" widgetVar="actionsDialog"
        dynamic="true" modal="true">
    ...
        <ui:include src="/WEB-INF/flows/actions-acc-flow/genericAccount.xhtml"/>
        ...
    </p:dialog>
</ui:composition>

/WEB-INF/flows/actions-acc-flow/genericAccount.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:custom="http://geneous.com/custom">
    <p:tabView id="tabs" value="#{accountsBean.groups}" var="group">
        <p:tab title="#{eval.getString(group.name)}">
            <p:dataTable id="editorsGroup" value="#{group.editors}" var="editor">
                <p:column>
                    <custom:include src="#{editor.component}" id="editor">
                        <ui:param name="beanName" value="#{editor.beanName}" />
                        <ui:param name="enabled" value="#{editor.enabled}" />
                        <ui:param name="mandatory" value="#{editor.mandatory}" />
                        <ui:param name="name" value="#{editor.name}" />
                    </custom:include>
                </p:column>
            </p:dataTable>
        </p:tab>
    </p:tabView>
</ui:composition>

/WEB-INF/flows/editors/accountsWindowsContainer.xhtml(此文件存储在editor.component 并包含在genericAccount.xhtml 中)

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:acme="http://java.sun.com/jsf/composite/acme">

    <acme:organizationUnit bean="#{windowsContainer}" mandatory="#{mandatory}"
        name="#{name}" id="accountWindowsContainer" />  
</ui:composition>

/webapp/resources/acme/organizationUnit.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:composite="http://java.sun.com/jsf/composite"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
    <!-- INTERFACE -->
    <composite:interface>
        <composite:attribute name="bean" type="java.lang.Object" required="true" />
        <composite:attribute name="mandatory" type="boolean" required="true"/>
        <composite:attribute name="name" type="java.lang.String" required="true" />
    </composite:interface>
    <!-- IMPLEMENTATION -->
    <composite:implementation>
        <h:panelGrid columns="2">
            <h:outputText value="#{cc.attrs.name}: #{cc.attrs.mandatory ? '*' : ''}" />
            <p:tree value="#{cc.attrs.bean['root']}" var="node" 
                selectionMode="single" selection="#{cc.attrs.bean['selectedNode']}">
                <p:ajax event="select" listener="#{cc.attrs.bean['onNodeSelect']}"
                    update="absolute_id_of_organization_unit" />
                <p:treeNode>
                    <h:outputText value="#{node}" />
                </p:treeNode>
            </p:tree>
            <h:outputText />
            <p:inputText id="organizationUnit"
                value="#{cc.attrs.bean['selectedItemPath']}"
                disabled="true" />
        </h:panelGrid>
    </composite:implementation>
</html>  

【问题讨论】:

    标签: java jsf jsf-2


    【解决方案1】:

    :form:tabs:editorsGroup:editor:accountWindowsContainer:organizationUnit不是组件的绝对id吗?

    只有当您从&lt;h:form&gt;删除 prependId="false" 并且您可以确保您的&lt;custom:include&gt; 实现NamingContainer 时,这就是它。如果后者不正确,则需要从绝对 ID 中删除 :editor 部分。

    【讨论】:

    • 如果我不删除 prependId="false" 并且 实现了 NamingContainer,那么绝对 id 将是 :tabs:editorsGroup:editor:accountWindowsContainer:organizationUnit?
    • 必须以任何方式删除prependId="false" 才能使此构造正常工作。 prependId 只是客户端,而不是服务器端。您必须在前面使用:form,无论prependId设置如何,它都会在服务器端找到组件,但是当它设置为false时,客户端的JS/ajax将无法找到它为了更新它。
    • 当一个节点被选中时,onNodeSelected 事件,selectedItemPath 属性被更新为新值,并且更新语句应该在一个节点被选中后更新 organizationUnit 组件。
    • 在 genericAccountTable.xhtml 中,在 genericAccounts 数据表之前有一个 &lt;f:event type="preRenderView" listener="#{accountsBean.preRenderView}" /&gt;。如果我去掉prependId="false",使用上面的绝对id,不带editor,preRenderView方法会被连续调用。
    • 请定义“连续”。这个监听器方法应该在每个渲染响应阶段之前被调用一次。
    猜你喜欢
    • 2015-07-16
    • 2010-11-14
    • 1970-01-01
    • 2016-04-23
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    相关资源
    最近更新 更多