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

发布于 2024-12-25 02:58:36 字数 2637 浏览 2 评论 0原文

这种奇怪的行为只发生在 Firefox(特别是 Firefox 8)中。所以我有一个可以进行多项选择的数据表。提交按钮,将在 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
 }

This odd behavior only happen in Firefox (specifically Firefox 8). So I have a dataTable that I can do multiple selection. A submit button, that will display a list of selected items to a dataList and to a dialog. If the user did not select anything, then a error msg come up asking the user to select something. The dialog will not appear if the user select nothing. The below code does all that. However FireFox behaves oddly if you do these follow:

  1. Click to select an item on the dataTable
  2. Then refresh (F5 or Ctl + R) the page (you can see the selection got clear off)
  3. Then click submit, it show whatever I just selected.

This is unexpecting, since the refresh should clear out whatever you just select due to nature of @ViewScoped bean. This behavior only happen in Firefox. IE 8 behave correctly for me. Is this a bug, or am I doing something wrong here?

Mojarra 2.1 + PrimeFaces3.0 Final + Tomcat 7

UPDATE: I did some debugging, when I refresh page, the value of the array selectedFoods become null, but for some odd reason, when it get to public void checkSelection(), it hold the value of the previous selection. So odd.

Here is my code.

<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>

Here is my managed 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
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绳情 2025-01-01 02:58:36

你的代码没问题。你所看到的是因为一些应该是 Firefox 的功能(我能够在 FF4 上重现这一点)。 p:dataTable 的选择模型是通过隐藏表单字段实现的。重新加载页面时,Firefox 会尝试保存和恢复已更改的表单字段值,以便您不会丢失输入的内容。您可以通过在视图中添加 、在输入中键入内容并重新加载来观察这一点。

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

Your code is fine. What you're seeing is because of something that is supposed to be a feature of Firefox (I was able to reproduce this on FF4). The selection model for p:dataTable is implemented with a hidden form field. When reloading a page, Firefox tries to save and restore form field values that have changed so that you don't lose what you entered. You can observe this by adding a <h:inputText/> to your view, typing something in the input, and reloading.

I'm not sure that the Firefox team meant for this to apply to hidden form fields, but I figure there's a decent chance that they did. I plan to file a bug report with Primefaces to either initialize the hidden input or to read the input on load to make the p:dataTable selection match. Either solution should result in the rendered selection and the hidden selection model to be in sync.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文