如何在视图之间传递PrimeFaces AutoComplete值

时间:2017-12-20 22:35:37

标签: jsf primefaces jsf-2

我正在阅读,尝试和搜索,我不知道我做错了什么。我曾经在JSF之前的时代用JSP和Seam编程,并且我已经习惯了技术本身(好吧,有点),我是JSF 2.x的新手,我仍然需要掌握一些概念。我现在最大的问题是将参数从一个视图发送到另一个视图,以便对传递的值执行实际的业务逻辑。我的用例:

  1. 主页initiateQuery.xhtml带有多个选项搜索小部件(目前PrimeFaces自动完成带multiple="true",因为它在我的用例中提供了最好的用户体验,我相信)

    < / LI>
  2. 用户可以输入/选择一些值并点击启动业务流程的按钮。输入的值应传递到另一个视图,refineQuery.xhtml应显示它们,并且可以使用其他参数优化业务查询

  3. 我不知道如何存储在initiateQuery中选择的值,将它们传递给refineQuery并在那里检索它们以获取实际业务逻辑以及一些其他字段。我不得不承认,我有点失去了GETting,POSTing,Post-Redirect-Get flow的所有可能性,隐含的所有内容,viewParam s,FacesContext&#39}的成员, bean范围,按钮与commandButtons,以及如何连接所有这些部分。我尝试了很多东西,但没有运气,从一个错误转到另一个错误,从没有传递到&#34; bean范围大于参数的范围&#34; to&#34;无法使用null转换器设置值[]&#34;。

    我认为我的支持bean必须是视图作用域,因为会话范围不适用(用户可能在启动业务查询时未登录),并且请求范围太小 - 两个视图上都有一些组件(即p:gmap s)用ajax修改支持bean属性。我想我可以处理应用程序的其他方面,比如自动完成列表中的POJO,持久性,L10n,但是将表单值传递给另一个视图对我来说太过分了;)尽管我在途中遇到的一些错误可能是由于自动完成控件或一些PrimeFaces相关的东西,这对我来说是更普遍的问题,因为我甚至无法将输入的简单字符串传递到p:inputText :(

    您可以找到一个简化的示例,说明哪些不适合我,以及我希望在下面实现的目标。请记住,我是JSF的新手,代码从一次尝试演变为另一种,我不太了解某些方面,因此有些事情可能会丢失或多余。

    initQuery.xhtml:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:p="http://primefaces.org/ui"
    
          lang="#{localeBean.language}"
          >
    
    <f:view locale="#{localeBean.language}">
    
        <h:head>
        <title>#{msg.homeTitle}</title>
        </h:head>
    
        <f:metadata>
            <f:viewParam name="search" value="#{initQueryView.searchedServices}"/>
        </f:metadata>
        <body>
    
            <h:form>
                <p:autoComplete id="search"
                                multiple="true"
                                required="true"
                                value="#{initQueryView.searchedServices}"
                                completeMethod="#{initQueryView.completeService}"
                                var="serviceKey"
                                itemLabel="#{serviceKey}"
                                itemValue="#{serviceKey}"
                                forceSelection="true"
                                minQueryLength="1"
                                >
                    <p:ajax event="itemSelect" listener="#{initQueryView.onItemSelect}" />
                    <p:ajax event="itemUnselect" listener="#{initQueryView.onItemUnselect}" />
                    <p:column>
                        <h:outputText value="#{serviceKey}" />
                    </p:column>
                </p:autoComplete>
    
                <p:commandButton ajax="false" title="#{msg.search}" value="#{msg.search}" action="refineQuery?faces-redirect=true&amp;includeViewParams=true" >
                    <f:param name="search" value="#{initQueryView.searchedServices}"/>
                </p:commandButton>
            </h:form>
    
        </body>
    </f:view>
    </html>
    

    initQuery backing bean:

    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    import org.primefaces.event.SelectEvent;
    import org.primefaces.event.UnselectEvent;
    
    import com.google.common.collect.Lists;
    import com.google.common.collect.Sets;
    
    @ManagedBean
    @ViewScoped
    public class InitQueryView {
    
        private List<String> searchedServices = new ArrayList<>();
        private Set<String> availableServices = new HashSet<>();
    
        @PostConstruct
        public void init() {
    
            availableServices = Sets.newHashSet("ServiceA", "ServiceB", "ServiceC");
            searchedServices = new ArrayList<>();
        }
    
        public Set<String> getAvailableServices() {
            return availableServices;
        }
    
        public List<String> getSearchedServices() {
            return searchedServices;
        }
    
        public void setSearchedServices(List<String> searchedServices) {
            this.searchedServices = searchedServices;
        }
    
        public String searchSubmit() {
            return "refineQuery?faces-redirect=true&includeViewParams=true";
        }
    
        public List<String> completeService(String query) {
    
            query = query.toLowerCase();
            List<String> filteredServices = new ArrayList<String>();
    
    
            for(String candidateService : availableServices) {
                if(candidateService.toLowerCase().startsWith(query)) {
                    filteredServices.add(candidateService);
                }
            }
    
            return Lists.newArrayList(filteredServices);
        }
    
        public void onItemSelect(SelectEvent event) {
            String selected = (String)event.getObject();
            availableServices.remove(selected);
        }
    
        public void onItemUnselect(UnselectEvent event) {
            String selected = (String)event.getObject();
            availableServices.add(selected);
        }
    }
    

    refineQuery.xhtml:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui" lang="#{localeBean.language}">
    
    <f:view locale="#{localeBean.language}">
    
        <h:head>
            <title>#{msg.homeTitle}</title>
        </h:head>
    
        <f:metadata>
            <f:viewParam name="search" value="#{searchResultView.searched}"/>
        </f:metadata>
    
        <h:body>
            Services to search for: #{refineQueryView.searched}<br/>
        </h:body>
    </f:view>
    </html>
    

    refineQuery支持bean:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ManagedBean
    @ViewScoped
    public class RefineQueryView {
    
        private List<String> searched = new ArrayList<>();
    
    
        @PostConstruct
        public void init() {
            searched = Arrays.asList("No idea how to retrieve searched services from previous view...");
        }
    
        public List<String> getSearched() {
            return searched;
        }
    
        public void setSearched(List<String> searched) {
            this.searched = searched;
        }
    }
    

0 个答案:

没有答案