Jsf p:dataTable/p:dataGrid和f:setPropertyActionListener中的延迟加载

Jsf p:dataTable/p:dataGrid和f:setPropertyActionListener中的延迟加载,jsf,primefaces,datatable,lazy-loading,jsf-2.2,Jsf,Primefaces,Datatable,Lazy Loading,Jsf 2.2,我有一个如下 <p:dataTable var="row" value="#{testManagedBean.list}"> <p:column> <h:outputText value="#{row.subCatId}"/> </p:column> <p:column> <p:commandLink process="@this"> <

我有一个
如下

<p:dataTable var="row" value="#{testManagedBean.list}">
    <p:column>
        <h:outputText value="#{row.subCatId}"/>
    </p:column>

    <p:column>
        <p:commandLink process="@this">
            <h:outputText value="#{row.subCatName}"/>
            <f:setPropertyActionListener target="#{testManagedBean.subCatName}" value="#{row.subCatName}"/>
        </p:commandLink>
    </p:column>
</p:dataTable>
@ManagedBean
@RequestScoped
public final class TestManagedBean
{
    @EJB
    private final TestBeanLocal testService=null;
    private List<SubCategory>list;
    private String subCatName;

    @PostConstruct
    private void init()
    {
        list=testService.getSubCategoryList();
    }

    public List<SubCategory> getList() {
        return list;
    }

    public String getSubCatName() {
        return subCatName;
    }

    public void setSubCatName(String subCatName) {
        System.out.println("setSubCatName() called : "+subCatName);
        this.subCatName = subCatName;
    }
}
<p:dataTable var="row" value="#{testManagedBean}" lazy="true" rows="10" rowIndexVar="rowIndex">
    <p:column>
        <h:outputText value="#{row.subCatId}"/>
    </p:column>

    <p:column>
        <p:commandLink process="@this">
            <h:outputText value="#{row.subCatName}"/>
            <f:setPropertyActionListener target="#{testManagedBean.subCatName}" value="#{row.subCatName}"/>
        </p:commandLink>
    </p:column>
</p:dataTable>
单击
内部的
时,将调用与
关联的相应setter方法(
setSubCatName()
),并将该值正确设置为此托管bean中的目标属性
subCatName

我已经避免了很多事情,比如分页,以获得一个最小的示例


现在,我需要懒洋洋地填充这个
。我正在更改这个
和相应的托管bean,如下所示

<p:dataTable var="row" value="#{testManagedBean.list}">
    <p:column>
        <h:outputText value="#{row.subCatId}"/>
    </p:column>

    <p:column>
        <p:commandLink process="@this">
            <h:outputText value="#{row.subCatName}"/>
            <f:setPropertyActionListener target="#{testManagedBean.subCatName}" value="#{row.subCatName}"/>
        </p:commandLink>
    </p:column>
</p:dataTable>
@ManagedBean
@RequestScoped
public final class TestManagedBean
{
    @EJB
    private final TestBeanLocal testService=null;
    private List<SubCategory>list;
    private String subCatName;

    @PostConstruct
    private void init()
    {
        list=testService.getSubCategoryList();
    }

    public List<SubCategory> getList() {
        return list;
    }

    public String getSubCatName() {
        return subCatName;
    }

    public void setSubCatName(String subCatName) {
        System.out.println("setSubCatName() called : "+subCatName);
        this.subCatName = subCatName;
    }
}
<p:dataTable var="row" value="#{testManagedBean}" lazy="true" rows="10" rowIndexVar="rowIndex">
    <p:column>
        <h:outputText value="#{row.subCatId}"/>
    </p:column>

    <p:column>
        <p:commandLink process="@this">
            <h:outputText value="#{row.subCatName}"/>
            <f:setPropertyActionListener target="#{testManagedBean.subCatName}" value="#{row.subCatName}"/>
        </p:commandLink>
    </p:column>
</p:dataTable>

下面给出了相关的JSF管理

@ManagedBean
@RequestScoped
public final class TestManagedBean extends LazyDataModel<SubCategory> implements Serializable
{
    @EJB
    private final TestBeanLocal testService=null;
    private String subCatName;
    private static final long serialVersionUID = 1L;

    public String getSubCatName() {
        return subCatName;
    }

    public void setSubCatName(String subCatName) {
        System.out.println("setSubCatName() called : "+subCatName);
        this.subCatName = subCatName;
    }

    @Override
    public List<SubCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters)
    {
        setRowCount(4); //Just an example. Otherwise, fetch from the database.
        return testService.getSubCategoryList(first, pageSize, sortField, sortOrder, filters);
    }
}
@ManagedBean
@请求范围
公共最终类TestManagedBean扩展LazyDataModel实现可序列化
{
@EJB
私有最终测试BeanLocal testService=null;
私有字符串子名称;
私有静态最终长serialVersionUID=1L;
公共字符串getSubCatName(){
返回子目录名;
}
public void setSubCatName(字符串subCatName){
System.out.println(“setSubCatName()调用:“+subCatName”);
this.subCatName=subCatName;
}
@凌驾
公共列表加载(int-first、int-pageSize、字符串排序字段、排序器排序器、映射过滤器)
{
setRowCount(4);//只是一个示例。否则,从数据库中获取。
返回testService.getSubcategory列表(第一个,页面大小,排序字段,排序器,过滤器);
}
}
现在,当单击
内部的
时,与
关联的相应setter方法(
setSubCatName()
)将不被调用

只有当托管bean使用更广泛的作用域(如
@ViewScoped
)修饰时,
setSubCatName()
才会被调用(如果
lazy
设置为true)

(对于
)被延迟加载时,为什么
不能与请求范围的托管bean一起工作


在这种情况下,指定范围比请求范围更广的托管bean是强制性的吗?

是强制性的,因为基础模型必须是同一实例。即使它具有相同的值,也不会起作用

和你一样,我也遇到过这种行为: