jsf 2 - JSF 为每个 AJAX 请求调用视图参数



我有一个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 方法?

经过

大量小时尝试找到解决方法后,此问题的解决方案如下:

  1. 将托管Bean设置为@ViewScoped,以便在仍在同一页面上时成为相同的Bean

  2. 我没有从 attractionId 的 setter 中的数据库中检索实体,而是在视图作用域 bean 中引入了一个@PostConstruct方法,以使用如下代码通过 view 参数检索对象:

    @PostConstruct
    public void setupAttractionModel() {
        this.attractionId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(ATTRACTION_ID_VIEW_PARAM);
        // Lookup by attractionId ...
    }
    

    postconstruct方法在每个需要Bean的页面之前调用。

  3. 删除导致问题的<f:metadata>标签

实际上,更好的方法是将 setter 保留为简单的 setter 并使用延迟实例化模式:

  1. 在 setAttractionId 中设置一个 id 的实例变量(如果脏),并清除当前检索到的实例。如果变量不脏,则吸引力实例将保持未修改状态。
  2. 在 getter (getAttractionModel) 中,如果为 null,则使用吸引力 ID 检索吸引力实例。 对 getter 的后续调用将返回实例,而无需从 db 检索。
  3. 删除后构造

这将适用于 ViewScoped bean。

受管 Bean 中的资源库可能是请求作用域的。 尝试将受管 Bean 设置为 ViewScoped,看看这是否有区别。

相关内容

  • 没有找到相关文章

最新更新