Бин ViewScoped воссоздается каждый раз, когда я нажимаю кнопку commandButton в моей таблице данных - PullRequest
0 голосов
/ 29 февраля 2012

Я использую Primefaces версии 3.1.1, Mojarra 2.1.3, Netbeans 7.0.1, Glassfish Server 3.1.

Мое тестовое приложение использует шаблон лицевой стороны с макетом сверху, слева, содержимым, справа и снизус сырыми div и css.После того, как пользователь войдет в систему с управляемым контейнером jdbcrealm, ему будет представлен основной файл index.html, который использует указанный шаблон.

Я разместил навигационное меню на левой панели, которое впоследствии будет обновлять содержимое центральной панели с помощью ajax при нажатии на пункт меню.Центральная панель будет динамически обновляться в <ui:include> с помощью sessionScoped NavigationBean.

. На одной из страниц clientList.xhtml я поместил <p:dataTable> с кнопкой для просмотра деталей, выскакивая<p:dialog>.Я использую bean-компонент viewCoped для хранения списка данных, отображаемого в таблице данных.

Проблема в том, что, когда я нажимаю кнопку, чтобы выбрать строку в последнем столбце каждой строки, диалоговое окно вообще не появляется, и мое изображение p:ajaxStatus gif продолжает катиться бесконечно.Когда я отлаживаю программу с помощью netbeans, я замечаю, что конструктор вызывается снова, а предыдущий экземпляр исчезает после нажатия кнопки.

Это мой index.xhtml с использованием шаблона facelets.

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:composition template="/BySalesAutomationTemplate.xhtml">
    <ui:define name="title">
        <h:outputText value="Facelet Index Page"></h:outputText>
    </ui:define>
    <ui:define name="top">
        TOP
    </ui:define>
    <ui:define name="left">
        <ui:include src="users/menu#{request.isUserInRole('ADMIN') ? 'Admin' : 'User'}.xhtml" />
    </ui:define>
    <ui:define name="right">
        <h:outputText value="Cuba2 daan"></h:outputText>
    </ui:define>
    <ui:define name="maincontent">
        <c:if test="#{navigationBean.page!=null}">
            <ui:include src="#{navigationBean.page}.xhtml" />
        </c:if>
    </ui:define> 
    <ui:define name="bottom">
        <center>2012</center> 
    </ui:define>
  </ui:composition>
</html>

Это страница clientList.xhtml, которая отображается на центральной панели моего index.xhtml после нажатия на ссылку в меню на левой панели.

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui"
  xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <title>Client Listing</title>
</h:head>
<h:body>
    <p>Client List</p>
    <h:form>
        <h:commandButton action="#{authBackingBean.logout}" value="Logout" />
    </h:form>
    <f:view>
        <h:form id="formdetail" prependId="false">
            <p:ajaxStatus>
                <f:facet name="start">
                    <h:graphicImage value="images/loading.gif" />
                </f:facet>
                <f:facet name="complete">
                    <h:outputText value="" />
                </f:facet>
            </p:ajaxStatus>
            <p:growl id="growl" showDetail="true"/>
            <p:dataTable id="dtClientList" value="#{saClientController.lazyModel}" rowsPerPageTemplate="10,20,30,50" 
                         paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" 
                         paginatorAlwaysVisible="false" var="item" paginator="true" rows="10">
                <f:facet name="header">
                    <h:outputText value="Client List"/>
                </f:facet>
                <p:column filterBy="#{item.idSaClient}">
                    <f:facet name="header">
                        <h:outputText value="IdSaClient"/>
                    </f:facet>
                    <p:commandLink action="#{saClientController.showDetails(item)}" value="#{item.idSaClient}" target=":maincontent"/>                        
                </p:column>
                <p:column filterBy="#{item.saClientName}">
                    <f:facet name="header">
                        <h:outputText value="saClientName"/>
                    </f:facet>
                    <h:outputText value="#{item.saClientName}"/>
                </p:column>
                <p:column filterBy="#{#item.saClientAddress}">
                    <f:facet name="header">
                        <h:outputText value="SaClientAddress"/>
                    </f:facet>
                    <h:outputText value="#{item.saClientAddress}"/>
                </p:column>
                <p:column style="width:40px">  
                    <h:panelGrid columns="3" styleClass="actions" cellpadding="2">  
                        <p:commandButton id="selectButton" update=":formdetail:display" oncomplete="clientDialog.show()" icon="ui-icon-search" title="View">                                  
                            <f:setPropertyActionListener value="#{item}" target="#{saClientController.selectedSaClient}" />  
                        </p:commandButton>  
                    </h:panelGrid>  
                </p:column>  
                <f:facet name="footer">
                    <h:outputText value="Client List"/>
                </f:facet>
            </p:dataTable>                      
        </h:form>

        <p:dialog id="clientDialog" header="Client Detail" widgetVar="clientDialog" resizable="false" showEffect="explode" hideEffect="explode">
            <h:panelGrid id="display" columns="2" cellpadding="4"> 
                 <f:facet name="header"> 
                     <h:outputText value="Selected Row" />
                 </f:facet> 
                 <h:outputText value="ID" />
                 <h:outputText value="#{saClientcontroller.selectedSaClient.idSaClient}" />
                 <h:outputText value="NAME:" /> 
                 <h:outputText value="#{saClientcontroller.selectedSaClient.saClientName}" /> 
                 <h:outputText value="DESCRIPTION:" />  
                 <h:outputText value="#{saClientcontroller.selectedSaClient.saClientAddress}" />  
             </h:panelGrid>
        </p:dialog>                   

    </f:view>
  </h:body>
</html>

Это мой компонент поддержки.

public class SaClientController implements Serializable {

    @EJB
    private SaClientFacade saClientFacade;
    private SaClient selectedSaClient;
    private LazyDataModel<SaClient> lazyModel;
    private List<SaClient> saclients;

    /** Creates a new instance of SaClientController */
    public SaClientController() {
    }

    @PostConstruct
    public void Init() {
        saclients = saClientFacade.Retrieve();
        lazyModel = new LazyDataModelImp(saclients);
    }

    public LazyDataModel<SaClient> getLazyModel() {
        return lazyModel;
    }

    public List<SaClient> getClients() {
        return saClientFacade.Retrieve();
    }

    public SaClient getDetails() {
        return selectedSaClient;
    }

    public String showDetails(SaClient selectedSaClient) {
        this.selectedSaClient = selectedSaClient;
        return "DETAILS";
    }

    public String update() {
        System.out.println("###UPDATE###");
        selectedSaClient = saClientFacade.Update(selectedSaClient);
        return "SAVED";
    }

    public String list() {
        System.out.println("###LIST###");
        return "LIST";
    }

    public SaClient getSelectedSaClient() {
        return selectedSaClient;
    }

    public void setSelectedSaClient(SaClient selectedSaClient) {
        this.selectedSaClient = selectedSaClient;
    }

    public String dummyAction()
    {
        return null;
    }
}

Это LazyModelImp класс

public class LazyDataModelImp extends LazyDataModel<SaClient> {

    private List <SaClient> datasource;

    public LazyDataModelImp(List<SaClient> datasource) {
        this.datasource = datasource;
    }

    @Override
    public SaClient getRowData(String rowKey) {
        for (SaClient saclient : datasource) {
            if (saclient.getIdSaClient().toString().equals(rowKey)) {
                return saclient;
            }
        }
        return null;
    }

    @Override
    public Object getRowKey(SaClient saclient) {
        return saclient.getIdSaClient().toString();
    }

    @Override
    public List<SaClient> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        List<SaClient> data = new ArrayList<SaClient>();
        //filter        
        for (SaClient saclient : datasource) {
            boolean match = true;
            for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                try {                    
                    String filterProperty = it.next();
                    String filterValue = filters.get(filterProperty);
                    String fieldValue = String.valueOf(saclient.getFilterSortFieldValue(filterProperty));
                    if (filterValue == null || fieldValue.startsWith(filterValue.toUpperCase()) || fieldValue.startsWith(filterValue.toLowerCase())) {
                        match = true;
                    } else {
                        match = false;
                        break;
                    }
                } catch (Exception e) {
                    match = false;
                }
            }
            if (match) {
                data.add(saclient);
            }
        }
        //rowCount
        int dataSize = data.size();
        this.setRowCount(dataSize);
        //paginate
        if (dataSize > pageSize) {
            try {
                return data.subList(first, first + pageSize);
            } catch (IndexOutOfBoundsException e) {
               return data.subList(first, first + (dataSize % pageSize));
            }
        }
        else {
            return data;
        }
        //sort
        //if (sortField != null) {
        //    Collections.sort(data, new LazySorter(sortField, sortOrder));
        //}       
        //return data;
    }
}

Я уже отключил частичное сохранение состояния в web.xml.

<context-param> 
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> 
    <param-value>false</param-value> 
</context-param> 

BackingBean повторно инициализируетсяпервый раз, когда я щелкаю по кнопке представления сведений в последнем столбце таблицы данных в clienList.xhtml.И диалог не отображается вообще.Но после нажатия F5.Диалоговое окно может отображаться, но без какого-либо содержимого, единственное, что отображается в диалоговом окне, это метка outputText, но не значения bean-компонентов, они пусты.Извините за вопрос новичка.Я буду очень рад, если кто-нибудь посоветует, что я делаю неправильно, и, может быть, немного посоветую о навигации и о том, соответствует ли моя стратегия отображению всего в index.xhtml (поэтому у меня все время есть только один идентификатор вида, который равен index.xhtml, верно?) верно.

1 Ответ

0 голосов
/ 29 февраля 2012

Это может быть проблема с вашим диалогом PrimeFaces, когда у вас есть h:form, окружающий p:dialog. Я заметил, что диалог PrimeFaces не работает должным образом, когда дочерний элемент элемента формы.

Попробуйте поместить эту диалоговую форму внутри содержимого диалога.

<p:dialog id="clientDialog" header="Client Detail" widgetVar="clientDialog" resizable="false" showEffect="explode" hideEffect="explode">
  <h:form id="formdialog" prependId="false">
    <h:panelGrid id="display" columns="2" cellpadding="4">
    ...
...