JSF вызывает параметры просмотра для каждого запроса AJAX

#jsf #jsf-2 #primefaces

#jsf #jsf-2 #простые

Вопрос:

У меня есть страница JSF, которая принимает viewparam и устанавливает переменную, которая ищет соответствующий объект из базы данных и загружает компонент с найденными деталями следующим образом:

 <f:metadata>
    <f:viewParam name="attractionId" value="#{attractionsBean.attractionId}" />
</f:metadata>
  

У меня есть карта Google, использующая API primefaces, и при перетаскивании маркера выполняется вызов 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:

Решение этой проблемы заключается в следующем после долгих часов попыток найти обходной путь:

  1. Сделайте ManagedBean как @ViewScoped , чтобы быть тем же компонентом, оставаясь при этом на той же странице

  2. Вместо извлечения объекта из базы данных в установщике attractionId я ввел @PostConstruct метод в компоненте view scoped для извлечения объекта с помощью параметра view, используя следующий код:

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

    Метод postconstruct вызывается перед каждой страницей, для которой требуется компонент.

  3. Удалите <f:metadata> тег, который вызывает проблему

Комментарии:

1. Это сработает, но я хотел бы сообщить, что управляемые свойства ДЕЙСТВИТЕЛЬНО работают с компонентами ViewScoped, я постоянно использую их в своем приложении Primefaces. Хитрость в том, что я сохраняю ссылки на объекты моей модели домена в экземпляре управляемого компонента и извлекаю их из базы данных только в том случае, если эти ссылки имеют значение null или когда они явно вызываются. Делая это таким образом, я могу выполнить ряд манипуляций с объектами в рамках моего представления и фактически не отправлять изменения базы данных, пока это явно не будет вызвано. Ссылки очищаются после завершения жизненного цикла управляемого компонента.

2. @maple_shaft извините за мою ошибку, тогда r.e. управляемое свойство .. но у меня была проблема с введением строкового значения, но, по крайней мере, это сработало .. спасибо за вашу помощь

Ответ №2:

Действительно, лучший способ — сохранить установщик как простой установщик и использовать шаблон отложенного создания экземпляра:

  1. Задайте переменную экземпляра с идентификатором в setAttractionId, если она загрязнена, и очистите текущий извлеченный экземпляр. Если переменная не загрязнена, экземпляр аттракциона останется неизмененным.
  2. В получателе (getAttractionModel) извлеките экземпляр аттракциона, если он равен нулю, используя идентификатор аттракциона. Последующие вызовы средства получения вернут экземпляр без извлечения из базы данных.
  3. Удалите конструкцию post

Это будет работать с компонентом ViewScoped.

Ответ №3:

Установщик в вашем управляемом компоненте может находиться в области запроса. Попробуйте установить для управляемого компонента значение ViewScoped и посмотреть, имеет ли это значение.

Комментарии:

1. Управляемый компонент был фактически сеансовым компонентом, чтобы предотвратить это.. который является более широкой областью, чем ViewScoped

2. Что ж, тогда это имеет смысл. Почему это проблема, что это вызывается каждый раз?

3. Проблема в том, что при установке идентификатора я извлекаю соответствующий объект из базы данных. Если это вызывается каждый раз, оно будет обновляться при каждом вызове. Я обнаружил обходной путь и опубликовал его в качестве ответа 🙂 В любом случае спасибо