每个ajax请求都会调用@ViewScoped @PostContruct

HDo*_*oan 3 ajax jsf primefaces view-scope

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

我在下面有这个Managed 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我从下面的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>
Run Code Online (Sandbox Code Playgroud)

我注意到每次扩展行init()都会被调用.@ViewScoped当请求停留在同一页面时,我以为还活着.

当我切换到时@SessionScoped,init()当我展开一行时不会被调用.

编辑1:将整个xhtml放入,指定jsf version/impl

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

Bal*_*usC 7

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

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

如果(ajax)请求中缺少此信息,那么JSF将简单地创建一个全新的视图,并且本质上也是与其关联的所有视图范围的bean.