如果从表单触发Ajax并更新另一个表单,Facelets是否会重建整个页面?

时间:2013-04-26 10:57:49

标签: jsf facelets jsf-2.2

设定: 我有两种形式A&乙 我有一个表格A的命令链接:

<h:commandLink actionListener="#{homeView.selectDiv('homeUpdates')}">#{msg.homeUpdates}
   <f:ajax render=":B" execute="@this" />
</h:commandLink>

...更新表格B.

问题是,当我点击ajax链接时,它也会重建表单A并从ui获取异常:重复我有。这是正确的行为吗?它是否应该重建形式A?

我使用的是JSF 2.2,表单A包含一个ui:fragment =&gt; ui:include =&gt; ui:repeat

=====添加了SSCCE ======= 按下更新B后,以下代码无法运行!两次。它给出了重复id的例外。 ui:repeat的值无关紧要

<h:head>
</h:head>

<h:body>
    <h:form id="A">
        <ul class="tableView notification">
            <ui:repeat var="notification" value="#{dashboardBean.notifications}">
                <li>
                    xx
                </li>
            </ui:repeat>
        </ul>

        <h:commandLink value="Update B!" listener="#{dashboardBean.toggleRendered}">
            <f:ajax execute="@this" render=":B" />
        </h:commandLink>

    </h:form>

    <h:form id="B">
    </h:form>
</h:body>

1 个答案:

答案 0 :(得分:1)

初次请求时,视图已创建,在回发后视图将被恢复。为了清楚起见,请背诵JSF 2.2 specification的某些要点(强调我的):

<强> P上。 2.2.1 :

  

如果请求不是回发...请在ViewHandler上调用 createView()。如果请求是回发,...调用ViewHandler。 restoreView(),传递当前请求和视图标识符的FacesContext实例,并为恢复的视图返回UIViewRoot。

<强> P上。 2.5.8

  

JSF视图中的选定组件可以被priocessed(称为部分处理),选定的组件可以呈现给客户端(称为部分渲染)。

<强> P上。 13.4

  

JavaServer Faces生命周期可以被视为由执行阶段和呈现阶段组成。部分遍历是一种可用于“访问”视图中的一个或多个组件的技术,可能使它们通过请求处理生命周期的“执行”和/或“渲染”阶段。

当您使用AJAX时,PartialViewContext类将包含遍历已恢复视图所需的所有信息。


因此,要回到您的问题,请在<f:ajax render=":B" execute="@this" />设置下,只有id="B"的表单会被重新呈现,这意味着<h:form id="B">,没有表单嵌套等。

关于你的'不工作'注释,带有普通视图范围的托管bean的简单测试用例给了我预期的结果:

<h:form id="A" >
    <h:outputText value="#{twoFormsBean.a}"/>
    <h:commandLink actionListener="#{twoFormsBean.actionA}">
        Update B!
        <f:ajax execute="@this" render=":B"/>
    </h:commandLink>
</h:form>
<h:form id="B" >
    <h:outputText value="#{twoFormsBean.b}"/>
    <h:commandLink>
        Update Both!
        <f:ajax execute="@this" render=":A :B"/>
    </h:commandLink>
</h:form>

@ManagedBean
@ViewScoped
public class TwoFormsBean implements Serializable {

    private String a = "A";//getter
    private String b = "B";//getter

    public void actionA(ActionEvent ae) {
        a = "newA";
        b = "newB";
    }

}