@ViewScoped @PostContruct 在每个 ajax 请求时被调用

@ViewScoped @PostContruct is called upon every ajax request

使用 Primefaces 5.0,JSF 2.2.7,部署在 EAP 6.1 上。

我在下面有这个托管 Bean。

import hh.bean.Service;
import hh.dao.ServiceDao;
import hh.dao.impl.ServiceDaoImpl;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class View1 implements Serializable {

    private static final long serialVersionUID = 1L;

    private ServiceDao serviceDao = new ServiceDaoImpl();

    @PostConstruct
    public void init() {
        System.out.println(View1.class.getName() + ": init() " + this);
    }

    public List<Service> getServices(){
        return serviceDao.getAllServices();
    }
}

我从下面的 xhtml 调用它。

<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:p="http://primefaces.org/ui">
<h:head>
    <title>Home Web</title>
    <f:facet name="first">
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta http-equiv="Content-Type"
            content="text/html; charset=UTF-8" />
        <meta name="viewport"
            content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
    </f:facet>
</h:head>

<h:body>
    <h:outputStylesheet library="css" name="newcss.css" />
    <p:dataTable var="service" value="#{view1.services}">
        <p:column style="width:16px">
            <p:rowToggler />
        </p:column>
        <p:column headerText="Id">
            <h:outputText value="#{service.id}" />
        </p:column>

        <p:column headerText="xxxx">
            <h:outputText value="#{service.description}" />
        </p:column>

        <p:rowExpansion>
            <p:dataTable var="sv" value="#{view1.services}">
                <p:column headerText="Id">
                    <h:outputText value="#{sv.id}" />
                </p:column>
            </p:dataTable>
        </p:rowExpansion>
    </p:dataTable>
</h:body>
</html>

我注意到每次展开行时我的 init() 都会被调用。我认为 @ViewScoped 会在请求停留在同一页面上时继续存在。

当我切换到 @SessionScoped 时,展开一行时 init() 没有被调用。

编辑1:把整个xhtml放进去,指定jsfversion/impl

编辑 2: 通过用 h:form 包围 p:dataTable 解决了这个问题。不知道为什么修复它...

Fixed this issues by surrounding the p:dataTable with h:form. Not sure why that fixed it...

JSF 视图状态由 <h:form>javax.faces.ViewState 隐藏输入字段维护。如果您不使用 <h:form>,那么 PrimeFaces 将无法找到隐藏的输入字段以便将其值与 jQuery ajax 请求一起传递。

如果 (ajax) 请求中没有此信息,那么 JSF 将简单地创建一个全新的视图,并且固有地也创建与之关联的所有 view 作用域 bean .