【问题标题】:Update component without specifying the absolute client id在不指定绝对客户端 ID 的情况下更新组件
【发布时间】:2012-09-13 12:55:49
【问题描述】:

下面的代码片段代表一个编辑器。在我的应用程序中,一个窗口在选项卡面板中显示一组编辑器,每个选项卡都包含一个数据表,其中编辑器作为行。当一个节点被选中时,其文本将显示在 organizationUnit 输入文本中。编辑不应该知道它的父母。是否可以在不使用绝对客户端 ID 的情况下更新 organizationUnit?

<p:tabView value="#{accountsBean.groups}" var="group">
    <p:tab title="#{eval.getString(group.name)}">
        <p:dataTable value="#{group.editors}"
            var="editor">                       
            <p:column>
                 <custom:include src="#{editor.component}">
                     <ui:param name="bean" value="#{editor.beanName}"/>
                     <ui:param name="mandatory" value="#{editor.mandatory}"/>
                     <ui:param name="name" value="#{editor.name}"/>
                 </custom:include>
            </p:column>
        </p:dataTable>
    </p:tab>                        
</p:tabView>

<h:panelGrid id="containerEditor" columns="2">
    <h:outputText value="#{name}: #{mandatory ? '*' : ''}" />
    <p:tree value="#{bean.root}" var="node" selectionMode="single" selection="#
        {selectedNode}">
        <p:ajax event="select" listener="#{bean.onNodeSelect}"
            update="update_organization_unit" immediate="true" />
        <p:treeNode>
            <h:outputText value="#{node}" />
        </p:treeNode>
    </p:tree>
    <h:outputText />
    <p:inputText id="organizationUnit" value="#{bean.selectedItemPath}"
        disabled="true" />
</h:panelGrid>

标签面板位于名为 form 的表单中,其中 prependId="false"

【问题讨论】:

  • 我很难理解你的问题,是什么阻止你使用update="organizationUnit"?您还应该明确代码的下部是某种组件,并发布 custom:include 的完整代码
  • @RasmusFranke 我理解了这个问题,它确实与代码有关。他不能这样做,因为 &lt;p:inputText> 和 &lt;p:ajax&gt; 在不同的 NamingContainers 中。
  • ajax 事件位于命名容器内,该命名容器位于 inputText 的命名容器内。如果当前容器中不存在 id,我认为 JSF 会在父容器中查找。
  • 如果我在更新语句中使用 organizationUnit 严重:javax.faces.FacesException:找不到标识符为“organizationUnit”的组件,该组件引用自“j_idt85:0:j_idt88:4:j_idt903:j_id647446661_47d7f77b: j_idt2"。
  • ajax事件在p:treeTable里面,它是一个命名容器,输入文本有datatable作为命名容器。

标签: java jsf primefaces


【解决方案1】:

当您在不同的 NamingContainers 中有组件,并且这些组件没有嵌套**时,您必须使用绝对客户端 ID。

在您的情况下,如果您在开始时不使用分隔符,则 findComponent 算法将向上搜索,直到找到 NamingContainer:这将是您的p:tree。然后它会尝试在p:tree中找到组件,因为它不存在,所以抛出你提到的异常。

另一方面,如果您确实在开头使用分隔符,则必须使用绝对客户端ID。

简短回答:不。除非您更改组件的组织方式,否则您无法在不使用绝对客户端 ID 的情况下更新 organizationUnit


** 如果 NamingContainers 是嵌套的,outter NamingContainer 内的组件可能会更新 inner NamingContainer 内的组件,方法是在他们想要的实际组件的 id 之前引用它们的 id更新,例如:update="innerContainer1Id:componentId",甚至是update="innerContainer1Id:innerContainer2:componentId"


Algorithm is explained in the JavaDoc.

【讨论】:

    【解决方案2】:

    我用来避免引用 id 的一个常见“技巧”是使用绑定。

    例子:

    <h:form>
        <p:button binding="#{button}" ...
    </h:form>
    
    ....
    <p:button update=":#{button.clientId}" ...
    

    注意:这不适用于像h:outputText 这样不生成 id 的标签。

    【讨论】:

      猜你喜欢
      • 2011-08-24
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      相关资源
      最近更新 更多