1

我有这个页面:

      <h:head></h:head>
    <h:body>
        <h:form id="someForm">
            Form is here
        </h:form>
        <h:form>
            <a4j:commandButton id="editButton" value="editSomeString"
                            execute="@this"
                            action="#{testBean.edit('afterEdit')}"
                            oncomplete="#{rich:component('editPanel')}.show()"
                            render="editPanel"/>
            <rich:popupPanel modal="true" id="editPanel" autosized="true"
                          domElementAttachment="form">
                <f:facet name="controls">
                    <a4j:ajax event="show" oncomplete="alert('#{testBean.someString}')" />
                </f:facet>
                Changed value is          
                #{testBean.someString}
            </rich:popupPanel>
        </h:form>
    </h:body>

使用这个 bean:

@ViewScoped
@ManagedBean(name = "testBean")
public class TestBean implements Serializable {

public TestBean() {
    someString = "initValue";
}
private String someString;


public String getSomeString() {
    return someString;
}


public void setSomeString(String someString) {
    this.someString = someString;
}


public void edit(String value) {
   someString = value;
}

}

现在,如果我单击弹出窗口中的按钮,我将获得正确的值(afterEdit),并在警报框中获得旧的值(initValue)。如果我删除第一个表单(id=someForm)或将 bean 范围更改为会话,它就可以正常工作(afterEdit 值显示在警报框中)。有什么想法吗?

我将此依赖项用于 jsf:

      <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.1.1-b04</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.1.1-b04</version>
        <scope>compile</scope>
    </dependency>

以及richfaces 4.0.0.Final 和 GlassFish Server 开源版 3.1.2(内部版本 23)

同一页面的另一个变体(添加了 onhide 和 onshow 方法)

<h:head></h:head>
    <h:body>
        <h:form id="someForm">
            Form is here
        </h:form> 
        <h:form>
            <a4j:commandButton id="editButton" value="go"
                            execute="@this"
                            action="#{testBean.edit('afterEdit')}"
                            oncomplete="#{rich:component('editPanel')}.show()"
                            render="editPanel,y"/>
            <rich:popupPanel modal="true" id="editPanel" autosized="true"
                             styleClass="taskEditPanel" domElementAttachment="form" onhide="alert('from on hide #{testBean.someString}')" onshow="alert('from on show #{testBean.someString}')">
                <f:facet name="controls">
                    <a4j:ajax event="show" oncomplete="alert('show complete #{testBean.someString}')"  />
                    <a4j:ajax event="hide" oncomplete="alert('hide complete  #{testBean.someString}')"/>
                </f:facet>
                Changed value is           
                #{testBean.someString}
                 <a4j:commandButton id="exitButton" value="exit"
                            execute="@this"
                            oncomplete="#{rich:component('editPanel')}.hide()"
                            />
            </rich:popupPanel>
        </h:form> 
    </h:body>

如果您尝试打开和关闭弹出窗口,则会出现这些警报:

  1. “来自编辑后的节目”
  2. “显示完整的 initValue”
  3. “从编辑后隐藏”
  4. “隐藏完整的 initValue”

所以看起来 a4j:ajax 从其他地方获取价值而不是弹出窗口上的方法?是 ViewState 问题吗?有两个隐藏的 javax.faces.ViewState 字段具有相同的 id 和不同的值。它们是代表整体视图的状态还是仅代表它们所包含的形式?如果整个视图这两个字段应该具有相同的值,并且可能 a4j:ajax 正在查看未更新的第一个表单的视图状态?任何关于如何处理视图状态以及它代表什么的资源链接都会很棒(即使这里的视图状态不是这种情况)

4

1 回答 1

1

您可以尝试使用相同的表单并a4j:region分隔不同的表单,因为 jsf 不喜欢更新其他表单,因为它们的状态不会发送到服务器当您使用时sessionScope,状态会保存在服务器中,这使得这成为可能,但它是不是真正的网络应用程序的最佳解决方案

于 2012-09-18T09:05:53.317 回答