Управляемый компонент jsf2 viewscope инициирован несколько раз

У меня проблема с bean-компонентом с областью видимости. Я знаю, что это общий вопрос, но я не получил правильного ответа. У меня есть таблица данных, которая отвечает за отображение результатов поиска по введенным пользователем критериям поиска. Вот xhtml:

<html   xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns="http://www.w3.org/1999/xhtml"

    xmlns:p="http://primefaces.org/ui">


<h:panelGroup id ="adminReportLogList">

<p:dataTable value="#{adminLogView.lazyModelReport}" var="model" id="reportLogList" lazy="true" paginator="true" rows="20" paginatorAlwaysVisible="false" paginatorPosition="bottom" emptyMessage="emppty list" styleClass="dtable" style="table-layout: fixed; width: 100%"
             paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15,20">

    <p:column headerText="Report number" sortBy="#{model.reportNumber}">
        <h:outputText value="#{model.reportLogId}"/>
    </p:column>
    <p:column headerText="Report date" sortBy="#{model.reportDate}">
            <h:outputText value="#{model.reportDate}">
                <f:convertDateTime pattern="yyyy/MM/dd hh:mm:ss"/>
            </h:outputText>
    </p:column>
    <p:column headerText="Search date" sortBy="#{model.searchLogId.searchDate}">
        <h:outputText value="#{model.searchLogId.searchdate}">
                <f:convertDateTime pattern="yyyy/MM/dd hh:mm:ss"/>
            </h:outputText>
    </p:column>
    <p:column headerText="User name" sortBy="#{model.searchLogId.loginLogId.username}">
        <h:outputText value="#{model.searchLogId.loginLogId.username}"/>
    </p:column>
    <p:column headerText="Customer number" sortBy="#{model.customerId}">
        <h:outputText value="#{model.customerId.registernumber}"/>
    </p:column>
    <p:column headerText="Customer name" sortBy="#{model.customerId}">
        <h:outputText value="#{model.customerId.name}"/>
    </p:column>
</p:dataTable>

</h:panelGroup>
<br/>

// SEARCH PANEL
<p:panel>
    <h:panelGrid columns="3" styleClass="insGrid" id="reportLogSearchPanel">
        <h:outputText value="User: "/>
        <p:inputText id="reportLogSearchByUserName" value="#{adminLogView.searchUserName}">
            <p:watermark for="reportLogSearchByUserName" value ="Customer name"/>
        </p:inputText>
        <h:message for="reportLogSearchByUserName" id="msgReportLogSearchByUserName" styleClass="errorMessage"/>

        <h:outputText value="Customer id number: "/>
        <p:inputText id="reportLogSearchByCustomerName" value="#{adminLogView.searchCustomerName}">
            <p:watermark for="reportLogSearchByCustomerName" value="Customer id number"/>
        </p:inputText>
        <h:message for="reportLogSearchByCustomerName" id="msgReportLogSearchBySearchDate" styleClass="errorMessage"/>

        <h:outputText value="Report date "/>
        <p:inputText id="reportLogSearchByReportDate" value="#{adminLogView.searchReportDate}">
            <p:watermark for="reportLogSearchByReportDate" value="Report date YYYY/MM/DD"/>
        </p:inputText>
        <h:message for="reportLogSearchByReportDate" id="msgReportLogSearchByReportDate" styleClass="errorMessage"/>

        <h:panelGroup/>
        <h:commandButton value="Search" styleClass="btn" action="#{adminLogView.searchReport()}">
            <f:ajax render =":form:adminReportLogList :form:reportLogList" execute=":form:reportLogSearchPanel"/>
        </h:commandButton>

    </h:panelGrid>

</p:panel>

which is used in tag in another xhtml which is: /I think it's not cause in this case/

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./../templates/admin_main.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui">

    <ui:define name="content">
        <h:panelGroup id="include">
        <ui:include src="#{adminLogView.page}.xhtml"/>
        </h:panelGroup>
    </ui:define>

</ui:composition>

вот моя фасоль

@Named(value = "adminLogView")
@ViewScoped
public class AdminLogView implements Serializable{
    @EJB
    private LogServiceLocal logService;
    private List<Reportlog> ReportLogList;

    String page = "reportLog";
    LazyDataModel<Reportlog> lazyModelReport;
    LazyDataModel<Loginlog>  lazyModelLogin;
    LazyDataModel<Searchlog> lazyModelSearch;

    String searchCustomerName;
    String searchUserName;
    String searchReportDate;


    @PostConstruct
    public void init(){

        this.lazyModelReport = new LazyReportLogDataModel(this.logService);
    }

    public void searchReport(){
        Map<String, String> filter = new HashMap<String, String>();
        if(this.searchCustomerName != null && !this.searchCustomerName.isEmpty())
            filter.put("customerName", this.searchCustomerName);
        if(this.searchReportDate != null && !this.searchReportDate.isEmpty())
            filter.put("reportDate", this.searchReportDate);
        if(this.searchUserName != null && !this.searchUserName.isEmpty())
            filter.put("userName", this.searchUserName);



        this.lazyModelReport.load(0, 30, null, SortOrder.UNSORTED, filter);

    }
}

Когда мы переходим на страницу выше, метод @postConstruct вызывается несколько раз, даже с sessionScoped. Даже когда мы нажимаем кнопку поиска в том же представлении, bean-компонент снова инициализируется. Только RequestScope работает нормально. Я что-то не так понял или забыл. PS. Заранее спасибо.


person Odgiiv    schedule 16.02.2013    source источник


Ответы (2)


У вас есть правильный SessionScoped? javax.enterprise.context.SessionScoped

У вас есть Myfaces CODI или любой другой адаптер на пути к классам? В противном случае @ViewScoped имеет недокументированное поведение, поскольку это область действия JSF-2.

Если у вас есть правильное @SessionScoped, то отмеченное поведение является совершенно неизвестной проблемой, по крайней мере, для меня.

Также:

@Named(value = "adminLogView")

значение, которое вы даете здесь, - это то, что по умолчанию. С тем же успехом можно пропустить такое значение настройки.

Удачи

person Karl Kildén    schedule 16.02.2013

@javax.faces.bean.ViewScoped не может работать с CDI. по этой причине вам необходимо использовать SeamFaces или MyFaces CODI, чтобы воспользоваться услугами viewscope.

CDI предлагает расширения для создания собственной области, чтобы вы могли реализовать контекст и использовать для этого @NormalScope.

  • CDI запускает событие AfterBeanDiscovery после каждого вызова компонента.
  • Вы можете использовать расширение CDI для @Observes этого события и добавить свою реализацию контекста.
  • In your scope implementation you can :
    1. Use Contextual to get your bean by its name from FacesContext ViewRoot Map and return it after each ajax call back
    2. Используйте CreationalContext, если имя компонента из первого шага не найдено, чтобы создать его в FacesContext ViewRoot Map.

для более подробного объяснения я рекомендую эту ссылку: http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/

person Kurohige    schedule 28.04.2013
comment
Это слишком простое описание в блоге. Как разработчик, я предпочитаю смотреть на код, который можно использовать. Как в Codi или DeltaSpike. - person Dar Whi; 01.05.2013
comment
лично мне просто нужно было получить свой bean-компонент после каждого обратного вызова ajax, реализация Стивена Верборга была полезна для меня с некоторыми адаптациями - person Kurohige; 01.05.2013
comment
Это то, что я сказал. Я не слежу за блогами, которые просто показывают половину правды, если я могу получить что-то, что также охватывает особые случаи. - person Dar Whi; 07.05.2013
comment
спасибо @darWhi Я думаю, что я должен опубликовать полную реализацию viewscope с использованием расширения cdi - person Kurohige; 09.05.2013