我有一个JSF页面,它接受一个viewparam并设置一个变量,该变量从数据库中查找相应的实体,并使用找到的详细信息加载bean,如下所示:
<f:metadata>
<f:viewParam name="attractionId" value="#{attractionsBean.attractionId}" />
</f:metadata>
我有使用primefaces API的谷歌地图,当拖动标记时,会发出ajax调用以更新标记位置。
<h:outputText value="Location" />
<f:view contentType="text/html">
<p:gmap id="gmap" center="41.381542, 2.122893" zoom="10" type="HYBRID" style="width:380px;height:350px"
model="#{attractionsBean.attractionModel.mapModel}"
markerDragListener="#{attractionsBean.onMarkerDrag}"
onMarkerDragUpdate="growl" />
</f:view>
问题是在每次标记拖动事件和ajax调用之后,每次都会调用元数据中的方法setAttractionId。
什么可以解决这个问题,以防止每次都调用setAttractionId方法?
答案 0 :(得分:1)
在尝试找到解决方法的许多小时之后,此问题的解决方案如下:
将ManagedBean设为@ViewScoped
,以便在同一页面上成为同一个bean
我没有在attractionId的setter中从数据库中检索实体,而是在视图范围bean中引入了一个@PostConstruct
方法,使用以下代码通过view参数检索对象: / p>
@PostConstruct
public void setupAttractionModel() {
this.attractionId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(ATTRACTION_ID_VIEW_PARAM);
// Lookup by attractionId ...
}
在每个需要bean的页面之前调用postconstruct方法。
删除导致问题的<f:metadata>
标记
答案 1 :(得分:1)
真的更好的方法是将setter保持为一个简单的setter并使用延迟的实例化模式:
这适用于ViewScoped bean。
答案 2 :(得分:0)
托管bean中的setter可能是请求作用域。尝试将托管bean设置为ViewScoped,看看是否会产生影响。