在JSF2中渲染表单范围之外的组件

时间:2012-05-29 17:23:35

标签: jsf java-ee jsf-2 el

我正在创建一个简单的页面,在单击按钮后,将一个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。

现在,当我尝试运行时,我得到了<f:ajax> contains an unknown id 'lol' - cannot locate it in the context of the component j_idt39。在谷歌搜索后,我发现对于表单范围之外的元素,我需要使用SEPARATOR_CHAR(:)。那没用。所以我尝试搞乱#{component}和#{cc}的不同组合,但没有任何效果。我甚至发现了this令人敬畏的解释,但同样,我失败了。如果我使用@all,一切正常(一个面板被另一个面板替换),但我真的需要渲染一个特定的组件。

帮助?请?

1 个答案:

答案 0 :(得分:5)

您需要更新公共父<div class="rightContent">。这个始终呈现,从而保证JavaScript / Ajax可以访问和维护其子项。将其替换为<h:panelGroup layout="block">并将其设为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中准确显示其:属性值(并以<f:ajax render>为前缀)。