【问题标题】:Firefox retain the content of an array inside JSF-Viewscoped-Managed-Bean even after refresh the page即使在刷新页面后,Firefox 也会在 JSF-Viewscoped-Managed-Bean 中保留数组的内容
【发布时间】:2012-02-04 13:19:48
【问题描述】:

这种奇怪的行为只发生在 Firefox(特别是 Firefox 8)中。所以我有一个dataTable,我可以做multiple selection。提交按钮,它将向dataListdialog 显示所选项目的列表。如果用户没有选择任何内容,则会出现一条错误消息,要求用户选择某些内容。如果用户不选择任何内容,则不会出现对话框。下面的代码完成了所有这些。但是,如果您执行以下操作,FireFox 的行为会很奇怪:

  1. 点击选择dataTable上的项目
  2. 然后刷新(F5 或 Ctl + R)页面(你可以看到选择被清除)
  3. 然后单击提交,它会显示我刚刚选择的任何内容。

这是出乎意料的,因为@ViewScoped bean 的性质,刷新应该会清除您刚刚选择的任何内容。这种行为只发生在 Firefox 中。 IE 8 对我来说表现正确。这是一个错误,还是我在这里做错了什么?

Mojarra 2.1 + PrimeFaces3.0 Final + Tomcat 7

更新:我做了一些调试,当我刷新页面时,数组selectedFoods的值变成了null,但是由于一些奇怪的原因,当它到达public void checkSelection()时,它保持前一个选择的值。好奇怪。

这是我的代码。

<p:growl id="messages" showDetail="true" />  
<p:messages id="msgs"/>
<h:form id="form">  
    <p:dataTable value="#{viewBean.foodList}" var="item" 
                  selection="#{viewBean.selectedFoods}"
                  selectionMode="multiple"
                  rowKey="#{item}">
        <p:column>
             #{item}
        </p:column>
        <f:facet name="footer">
            <p:commandButton value="Submit" update=":form:display :dataList" 
                                 action="#{viewBean.checkSelection}"/>
        </f:facet>
    </p:dataTable>
    <p:dataList id="display" value="#{viewBean.selectedFoods}" var="item"
                    itemType="disc">
        #{item}
    </p:dataList>
</h:form>
<p:dialog id="dialog1" widgetVar="dialog1" dynamic="true" width="200">
    <p:dataList id="dataList" value="#{viewBean.selectedFoods}" var="item"
                    itemType="disc">
        #{item}
    </p:dataList>
</p:dialog>

这是我的托管 bean

@ManagedBean
@ViewScoped
public class ViewBean implements Serializable {
    private List<String> foodList;
    private String[] selectedFoods;

    @PostConstruct
    public void init() {
        foodList = new ArrayList<String>();
        foodList.add("Pizza");
        foodList.add("Pasta");
        foodList.add("Hamburger");
    }

    public void checkSelection(){
        RequestContext requestContext = RequestContext.getCurrentInstance();
        if(selectedFoods.length > 0){
            requestContext.execute("dialog1.show()");
        }else{
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Error", "Please select"));
            requestContext.addPartialUpdateTarget("messages");
        }
    }
    //setter, getter
 }

【问题讨论】:

  • :P 如果您的代码可以在某些浏览器上正确运行,我会说您没有做错任何事情。如果您的服务器端代码在某处出错,它将出现在所有浏览器上^^
  • @Mr.J4mes :D 我想知道你是否产生了和我一样的结果?
  • 我还没有尝试,但我稍后会:P
  • FWIW:无法在 FF9 上重现。我手头没有FF8。

标签: jsf jakarta-ee jsf-2 primefaces java-ee-6


【解决方案1】:

您的代码很好。您所看到的是因为应该是 Firefox 的一个功能(我能够在 FF4 上重现此功能)。 p:dataTable 的选择模型是使用隐藏的表单字段实现的。重新加载页面时,Firefox 会尝试保存和恢复已更改的表单字段值,这样您就不会丢失输入的内容。您可以通过在视图中添加 &lt;h:inputText/&gt;、在输入中输入内容并重新加载来观察这一点。

我不确定 Firefox 团队是否打算将此应用于隐藏的表单字段,但我认为他们这样做的可能性很大。我计划向 Primefaces 提交错误报告,以初始化隐藏输入或在加载时读取输入以使 p:dataTable 选择匹配。任何一种解决方案都应该导致呈现的选择和隐藏的选择模型同步。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多