JSF preRenderView вызывается слишком много раз - PullRequest
5 голосов
/ 08 января 2012

Для страницы / моего объекта событие preRenderView запускается дважды при загрузке первой страницы, а затем 2 + n раз для каждой обратной передачи, где n - это количество обратных передач (включая текущую), которые произошли.

Прочитав несколько других постов здесь, я переместил <f:event type="preRenderView" listener="myBean.preRenderView"/> за пределы <f:metadata/>, и это уменьшило количество preRenderView вызовов на один. То есть он вызывается один раз при полной загрузке страницы и 1 + n раз для каждой обратной передачи. Я даже пытался переместить тег <f:event/> за пределы <f:view/>, но это не имело никакого эффекта.

Я не уверен, что это актуально: на странице используется шаблон:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:fb="http://www.facebook.com/2008/fbml">
    <f:view contentType="text/html">
        <ui:insert name="metadata"/>
        <h:head>
            <!-- Some stuff here -->
            <ui:insert name="content"/>
            <!-- More stuff here -->
        </h:head>
        <h:body>
        </h:body>
    </f:view>
</html>

И соответствующие биты страницы:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title></title>
    </h:head>
    <h:body>
        <ui:composition template="/WEB-INF/templates/myLayout.xhtml">
            <ui:define name="windowTitle">My Page</ui:define>
            <ui:define name="metadata">
                <f:event type="preRenderView" listener="#{myBean.preRenderView}"/>
            </ui:define>
            <ui:define name="content">
                <!-- Some content here -->
                <h:panelGroup id="reRenderable" layout="block">
                    <!-- More content here -->
                    <h:form prependId="false">
                        <h:outputLabel for="mySelector" value="Item:"/>
                        <h:selectOneMenu id="mySelector"
                                         value="#{myBean.item}"
                                         converter="#{myConverter}"
                                         validator="#{itemActiveValidator.validate}">
                            <f:selectItems value="#{myBean.myItems}"/>
                            <f:ajax render=":reRenderable"/>
                        </h:selectOneMenu>
                    </h:form>
                    <!-- More content here -->
                </h:panelGroup>
                <!-- More content here -->
            </ui:define>
        </ui:composition>
    </h:body>
</html>

Ответы [ 3 ]

5 голосов
/ 08 января 2012

Похоже, еще одна ошибка Mojarra: JAVASERVERFACES-2162

Я применил обходной путь следующим образом, и он работает:

<ui:define name="metadata">
    <f:metadata>
        <f:viewParam name="dummy"/>
        <f:event type="preRenderView" listener="#{myRecordsBean.preRenderView}"/>
    </f:metadata>
</ui:define>

Все, что осталось сделатьнажмите dummy вверх к шаблону, чтобы освободить страницы, которые его используют, от этой грязи.

0 голосов
/ 20 января 2012

Попробуй это. Я не знаю технических различий между вашим кодом и моим ниже. Я изменил <ui:insert name="content"/> расположение между тегами тела из тегов головы. И добавить f:metadata. Но когда я использую это, это не вызывает дважды. Работает нормально. Это может быть о структуре страницы. Может быть, об использовании HTML-тега дважды. Тебе нужен один. Но на полных страницах недостающие части, только недостающие части с композиционными блоками.

<!DOCTYPE html>
   <html xmlns="http://www.w3.org/1999/xhtml"
         xmlns:h="http://java.sun.com/jsf/html"
         xmlns:ui="http://java.sun.com/jsf/facelets"
         xmlns:f="http://java.sun.com/jsf/core"
         xmlns:fb="http://www.facebook.com/2008/fbml">

    <f:view contentType="text/html">
         <f:metadata>
             <ui:insert name="metadata"/>
          </f:metadata>


        <h:body>
              <!-- Some stuff here -->
              <ui:insert name="content"/>
              <!-- More stuff here -->
        </h:body>
     </f:view>
    </html>




<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
            xmlns="http://www.w3.org/1999/xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                template="/WEB-INF/templates/myLayout.xhtml">




        <ui:define name="windowTitle">My Page</ui:define>
        <ui:define name="metadata">
            <f:event type="preRenderView" listener="#{myBean.preRenderView}"/>
        </ui:define>
        <ui:define name="content">
            <!-- Some content here -->
            <h:panelGroup id="reRenderable" layout="block">
                <!-- More content here -->
                <h:form prependId="false">
                    <h:outputLabel for="mySelector" value="Item:"/>
                    <h:selectOneMenu id="mySelector"
                                     value="#{myBean.item}"
                                     converter="#{myConverter}"
                                     validator="#{itemActiveValidator.validate}">
                        <f:selectItems value="#{myBean.myItems}"/>
                        <f:ajax render=":reRenderable"/>
                    </h:selectOneMenu>
                </h:form>
                <!-- More content here -->
            </h:panelGroup>
            <!-- More content here -->
        </ui:define>
   </ui:composition>
0 голосов
/ 18 января 2012

попробуй

@ManagedBean
@XScoped --sessionScope,viewScope   
Public class MyRecordsBean{
public void preRenderView(){
 if (!FacesContext.getCurrentInstance().isPostback(){
 //put initView codes here
}

}

...