即使刷新页面后,Firefox 也会保留 JSF-Viewscoped-Managed-Bean 内数组的内容
这种奇怪的行为只发生在 Firefox(特别是 Firefox 8)中。所以我有一个可以进行多项选择的数据表。提交按钮,将在 dataList
和 dialog
中显示所选项目的列表。如果用户没有选择任何内容,则会出现一条错误消息,要求用户选择某些内容。如果用户未选择任何内容,则不会出现该对话框。下面的代码完成了这一切。但是,如果您执行以下操作,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" 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:
- Click to select an item on the
dataTable
- Then refresh (F5 or Ctl + R) the page (you can see the selection got clear off)
- 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的代码没问题。你所看到的是因为一些应该是 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.