即使在刷新页面后,Firefox 也会在 JSF-Viewscoped-Managed-Bean 中保留数组的内容

Posted

技术标签:

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

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

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

这是出乎意料的,因为@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" >
    <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。 【参考方案1】:

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

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

【讨论】:

非常感谢您的解释。如果您可以向 PrimeFaces 提交错误报告,我将不胜感激。 啊,对,那个字段应该有一个autocomplete="off"。 @Harry:您也可以在code.google.com/p/primefaces/issues 上举报自己 我去提交报告,它想要一个论坛主题来参考,所以我在那里发帖:forum.primefaces.org/viewtopic.php?t=17425。我必须了解有关自动完成的更多信息,因为听起来这可能是正确的解决方案。 @BalusC:我已经在code.google.com/p/primefaces/issues/detail?id=3263 提交了PF 的问题报告。谢谢各位

以上是关于即使在刷新页面后,Firefox 也会在 JSF-Viewscoped-Managed-Bean 中保留数组的内容的主要内容,如果未能解决你的问题,请参考以下文章

当页面自动刷新但在谷歌浏览器中没有时,语音在 Firefox 中被切断

即使自动完成关闭,文本也会自动填充到输入文本中

即使没有发出预检请求,也会在 POST 请求中出现 CORS 错误

带有 useEffect 的 Next.js useRouter 即使在页面刷新时满足条件也会推送

即使应用程序没有运行,Android也会在解锁屏幕后自动运行应用程序

即使定期报告我的活动,应用程序也会在 1 小时后过期