当使用lazy dataTable时,另一个组件没有得到更新/第二个组件数据是一个请求

jim*_*ndy 6 jsf lazy-loading primefaces jsf-2

我有一个PrimeFaces p:dataTable并通过实现一个启用延迟加载LazyDataModel.

dataTable保存搜索结果,因此在执行搜索请求时,搜索服务仅检索所需(分页)数据.这很好.

在执行ajax请求时p:commandButton:

<p:commandButton id="searchCmdBtn" value="Search" action="#{searchBean.search}" 
   update=":resultForm:resultList :filterForm:filterMenu :resultForm:messages" 
   ajax="true" />
Run Code Online (Sandbox Code Playgroud)

dataTable正确更新,但不是filterForm中的filterMenu(不同的形式,使用bcz p:layout).

filterMenu是一个请求.这意味着当我再次点击搜索按钮时,filterMenu会更新,t只会在第二次ajax请求后更新

@ManagedBean
@ViewScoped
public class SearchBean implements Serializable {

    private LazyDataModel<Entity> lazyDataModel;
    private MenuModel filterMenuModel = new DefaultMenuModel();
    private SearchResult searchResult = null;

    public void search() {   
        // lazy call
        getLazyDataModel();
        if (searchResult != null) {
            buildFilterMenu(searchResult);
        }
    }

    private void initializeDataModel() {

        lazyDataModel = new LazyDataModel<Entity>() {

            private static final long serialVersionUID = 1L;

            @Override
            public List<Entity> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, String> filters) {

                // handling sorting and filtering

                // get search results
                try {
                    setSearchResult(searchService.getEntities(queryText, selectedQueryOperand, getFilterOptions(), first, (first + pageSize), multiSortMeta));
                } catch (Exception e) {
                    // handle exception
                }
                if (searchResult == null) {
                    return null;
                }
                List<Entity> resultEntities = searchResult.getResultEntities();
                // total count
                this.setRowCount((int) searchResult.getTotalSize());
                return resultEntities;
            }

        // other override-methods     
        };
    }

    public void buildFilterMenu() {
        // builds the filterMenu depending on searchResults
    }


    // getters and setters

    public LazyDataModel<Entity> getLazyDataModel() {
        if (lazyDataModel == null) {
            initializeDataModel();
        }
        return lazyDataModel;
    }

}
Run Code Online (Sandbox Code Playgroud)

filters.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:fn="http://java.sun.com/jsp/jstl/functions">

    <p:panelMenu id="filterMenu" model="#{searchBean.filterMenuModel}" />

</ui:composition>
Run Code Online (Sandbox Code Playgroud)

jim*_*ndy 10

在搜索PF论坛后,我找到了根本原因:

在呈现响应阶段调用dataTable Lazy load()方法

要了解这些阶段,请阅读BalusC关于JSF生命周期的本教程

显示消息的解决方案(例如:p:messagesp:growl):

  1. 使用PrimeFaces RequestContext更新消息组件

    RequestContext.getCurrentInstance().update(":growlOrMsgID");
    
    Run Code Online (Sandbox Code Playgroud)

    这不起作用,因为那时添加额外的组件来更新已经太晚了.

  2. 使用dataTable属性errorMessage

    没有为dataTable找到此名称的属性

  3. 将p:messages或p:growl放在p:dataTable下面

    为我工作

  4. 使用RequestContext的PF执行方法

    当前的ajax请求完成后,RequestContext#execute()执行javascript.

    为我工作


也可以看看: