【发布时间】:2018-09-28 15:56:56
【问题描述】:
在视图main_app.xhtml中有5个不同的字段,每个字段都包含一个按钮,当点击这个按钮时,它必须打开视图chart_xxx.xhtml,它会显示一个图表,其中包含与该字段相关的不同数据场地
即:
General Rating 将在图表中显示一些数据 清洁评级将在图表中显示一些不同的数据 等等
当我单击按钮时,buildGraph() 方法被调用了几次,通常是 2 或 3 次,其中一些请求显示了请求中发送的参数,而另一些则没有,我不知道为什么会这样正在发生,因此
我决定将请求发送的参数存储在会话中,但是......我不知道为什么,如果我返回 main_app.xhtml,单击另一个按钮,视图 chart_xxx.xhtml 将显示来自先前发送的请求,
但如果我再次返回main_app.xhtml 并再次单击同一个按钮,则会显示正确的数据。
例如:
- 我点击General Rating按钮,它的数据显示在图表上。
- 返回
main_app.xhtml - 点击清洁评级
- 显示来自一般评级的数据。
- 返回
main_app.xhtml - 再次点击干净评级
- 清洁评级数据显示正确
我已多次阅读此主题Why JSF calls getters multiple times,但我无法找到使其适应我的功能的方法。
此外,如果我使用@RequestScoped,当我第二次单击按钮以显示图表时,图表将显示为空白。
请忽略句法问题,由于我的公司政策,我不得不更改一些名称,因此无法识别它,并且还从我的语言翻译,因此可能存在一些句法问题,但仅限于翻译。 我还省略了 Service 和 DAO 类,因为它们工作正常,它们返回了我对它们的期望。
我使用 Java 1.6、JSF 2.1 和 Primefaces 6.0
所以,我需要帮助解决这个问题,或者如果有人知道更好的方法,我会全神贯注,但在这种情况下,请尝试做一个扩展的答案,因为我真的想不出任何其他方法。
编辑 1
我删除了 Setter 和 Getter,以使我的代码对您来说更清晰,还删除了一些为 Chart 分配属性的代码,但所有这些都在我的原始代码中并且工作正常。
PollGraphicBean.java
@ManagedBean(name="pollGraphic")
@SessionScoped
public class GraficosEncuestaBean {
private LineChartModel graphicLine;
public GraficosEncuestaBean(){
if(graphicLine == null){
this.buildGraph();
}
}
public void buildGraph(){
HttpServletRequest parameterMap = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
String general = "";
String clean = "";
String date1 = "01-03-2017 00:00";
String date2 = "30-04-2017 00:00";
if(parameterMap != null){
if(general != null){
general = parameterMap.getParameter("general");
session.setAttribute("hidden", general);
}else if(clean != null){
clean = parameterMap.getParameter("clean");
session.setAttribute("hidden", clean);
}
this.buildGraphicFinal(date1,date2, (String) session.getAttribute("hidden"));
}
}
private void buildGraphicFinal(String date1, String date2, String value){
this.graphicLine = new PollGraphicService().getGraphicData(date1, date2, value);
}
}
chart_xxx.xhtml
<ui:define>
<p:panel>
<h:form>
<p:chart type="line" model="#{pollGraphic.graphicLine}" />
</h:form>
</p:panel>
</ui:define>
main_app.xhtml
<ui:define>
<p:panelGrid>
<p:column>
<p:panel>
<div>
<h:form prependId="false">
<input type="hidden" value="General Rating"
name="general" id="general"/>
<p:commandButton value="Get results"
actionListener="#{pollGraphic.buildGraph}" onstart="location.href =
'/XXX/chart/chart_xxx.xhtml'"/>
</h:form>
</div>
</p:panel>
</p:column>
<p:column>
<h:form prependId="false">
<input type="hidden" value="Clean Rating"
name="clean"/>
<p:commandButton value="Get results"
actionListener="#{pollGraphic.buildGraph}" onstart="location.href =
'/XXX/chart/chart_xxx.xhtml'"/>
</h:form>
</div>
</p:panel>
</p:column>
</p:panelGrid>
</ui:define>
【问题讨论】:
-
您为什么要以这种方式使用 parameterMap 并以这种方式填充会话...非常老派...并尝试减少您问题中的代码。噪音太大了...minimal reproducible example请
-
我添加了与我的问题有关的所有必要代码,我知道这不是最好的方法,但就像我说的那样,这是我能够找到的唯一方法对于 buildGraphic 方法被多次调用,我对如何以更好的方式管理它的建议持开放态度。
-
不,很多代码与问题无关。所有的 div、br 样式等 panelgrid 等都无关紧要。哦,不应使用 prependId="false".. stackoverflow.com/questions/7415230/…。而且你不应该在构造函数中做任何工作......甚至懒惰......使用@PostConstruct注解......
-
我重新格式化了我的 xhtml 代码,删除了其中的许多内容,我现在无法尝试 @PostConstruct 并删除 prependId,明天我到办公室时会这样做。
-
是的,但只有当你把事情弄清楚(你可以更清楚)我们才能看到真正的用例是什么,也许你哪里出错了......
标签: java jsf primefaces jsf-2