【问题标题】:Rendering a component outside the form's scope in JSF2在 JSF2 中呈现表单范围之外的组件
【发布时间】:2012-06-03 22:53:07
【问题描述】:

我正在创建一个简单的页面,该页面将在单击按钮后将一个 panelGroup 替换为另一个。一、代码:

<h:body>

    <ui:composition template="/elements/templateWithMenu.xhtml">           
        <ui:define name="content">
            <div class="rightContent">

                <h:panelGroup id="lol" rendered="#{test.firstStep.booleanValue()}">

                    <h3>This should disappear</h3>

                    <h:form id="newPollForm1" rendered="#{test.firstStep.booleanValue()}"> 
                        <fieldset>
                            <h:commandLink value="Next" action="#{test.firstStepCompleted()}" >
                                <f:ajax execute="@all" render="lol" />
                            </h:commandLink>
                        </fieldset>
                    </h:form>

                </h:panelGroup>

                <h:panelGroup rendered="#{test.secondStep.booleanValue()}">
                    Works!
                </h:panelGroup>

            </div>     
        </ui:define>
    </ui:composition>

</h:body>

支持 bean 只是将 firstStep 设置为 false,将 secondStep 设置为 true。

现在,当我尝试运行它时,我得到了&lt;f:ajax&gt; contains an unknown id 'lol' - cannot locate it in the context of the component j_idt39。谷歌搜索了一下,我发现对于表单范围之外的元素,我需要使用 SEPARATOR_CHAR (:)。那没有用。所以我尝试弄乱#{component}和#{cc}的不同组合,但没有任何效果。我什至找到了this 很棒的解释,但我又一次惨败。如果我使用@all,一切正常(一个面板被另一个面板替换),但我确实需要渲染一个特定的组件。

帮助?请问?

【问题讨论】:

  • 您是如何使用“SEPARATOR_CHAR (:)”的?难道你不能只使用 CSS\js 来实现吗?
  • ':lol' 和其他一些 ':something:somethingElse:lol'(我尽可能地剥离了附加的 xhtml)。

标签: jsf jakarta-ee jsf-2 el


【解决方案1】:

您需要改为更新公共父级&lt;div class="rightContent"&gt;。这个是总是呈现的,因此保证了 JavaScript/Ajax 可以访问和维护它的孩子。将其替换为&lt;h:panelGroup layout="block"&gt; 并给它一个id

<h:panelGroup layout="block" id="content" class="rightContent">
    <h:panelGroup rendered="#{test.firstStep}">
        <h3>This should disappear</h3>
        <h:form id="newPollForm1"> 
            <fieldset>
                <h:commandLink value="Next" action="#{test.firstStepCompleted()}" >
                    <f:ajax execute="@form" render=":content" />
                </h:commandLink>
            </fieldset>
        </h:form>
    </h:panelGroup>

    <h:panelGroup rendered="#{test.secondStep}">
        Works!
    </h:panelGroup>
</h:panelGroup>

使用这个Test.java 类:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class Test {
    private int number = 0;

    public void firstStepCompleted() {
        number++;
    }

    public boolean isFirstStep() {
        return number == 0;
    }

    public boolean isSecondStep() {
        return number == 1;
    }
}

请注意,我删除了表单上多余的 Boolean#booleanValue() 调用和重复的 rendered 连接。

如果这仍然不起作用,那么/elements/templateWithMenu.xhtml 显然包含另一个命名容器组件,该组件已预先添加其 ID。对于尚未记住所有命名容器组件的初学者来说,找出真正正确的客户端 ID 的一种简单方法是在浏览器中打开页面,右键单击并查看源代码,然后找到 JSF 生成的 HTML元素并准确获取其id 属性值(并在&lt;f:ajax render&gt; 中为其添加: 前缀)。

【讨论】:

  • 它可以工作(模板不是问题)!谢谢你。只是为了确保将来参考,'lol' 为什么不是共同的父母,或者在这种情况下,如果我在第二个 panelGroup 上使用 id="content" 而不是在第一个 panelGroup 上使用它会起作用吗?
  • 这就是 JavaScript/ajax 的工作原理。 JavaScript 要求要更新的元素总是由 JSF 呈现(因此在 JSF 源代码中没有rendered 条件)。否则 JavaScript 将无法访问它并操纵它的子节点。 JavaScript 永远不会删除整个元素,只会操纵/删除其子元素。
猜你喜欢
  • 2013-12-11
  • 1970-01-01
  • 2010-10-07
  • 2013-05-02
  • 2012-11-25
  • 2017-03-01
  • 1970-01-01
  • 2019-10-09
  • 1970-01-01
相关资源
最近更新 更多